2

I am using an array of objects to store data to render a page.

A few examples of the type of data each object can contain:

  • PHP filepath for an include
  • CSS filepath for CSS files
  • Meta data of the page
  • Element data to build page elements
  • Etc...

I have an HTML template file that I parse with PHP and replace certain tags in the template with data stored in the objects. A template tag looks like:

<!-- @CMS;TYPE=TITLE !-->
<!-- @CMS;TYPE=CSS !-->

These tags can also have more attributes:

<!-- @CMS;TYPE=JS-FILES;POS=TOP  !-->
<!-- @CMS;TYPE=JS-FILES;POS=BOTTOM !-->

The tags above contain a position and thus you can place your content of the same type in the top or the bottom of the template.


The data objects all use the same abstract class and have the same render function:

class PhpFragment extends FragmentBase {
  public function render() {
    //... render output for this type of data
  }
}

class CssFragment extends FragmentBase {
  public function render() {
    //... render output for this type of data
  }
}

class MetaFragment extends FragmentBase {
  public function render() {
    //... render output for this type of data
  }
}

This way I can use an universal function to render all the objects, unregarding the type of data it contains.

The Challenge

I need a way to quickly find certain objects inside the array. When I reach a certain tag inside the template, I need to render the data of the objects that match the type (and position if applicable) of this tag.

In my previous design I used an object with a lot of class properties that hold instances of FragmentBase, like:

class pageData {
  protected $mCSS;
  protected $mPHP;
  protected $mJS;
  protected $mMeta;
  protected etc...
}

Each class property contained an array of FragmentBase instances of a certain data-type to retrieve data from.

But this design isn't very easily maintained and is not very flexible. Also because the object that stored the data is universal, I needed to check the datatype to be able to render it with the correct function.

Is there a way to search through an array of objects fast or should I just stick to using the pageData object and store my fragment objects in that?

  • Do you mean to search and filter the objects of a certain type? – SOFe Jul 6 '16 at 15:30
  • Yes, thats what I mean. With an associative array you can just use the array keys, you cant do that with an array of objects, so how to search through objects? – PIDZB Jul 6 '16 at 15:32
  • And when were the FragmentBase objects created to be stored into the pageData index? So you reuse objects from the pageData index when you scan the whole HTML page again? – SOFe Jul 6 '16 at 15:40
  • 2
    @Abayob Why can't you use an associative array with objects? If tag is your lookup key, use that as the associative key and a reference to the full object instance as the value. If there is more than one value you want to be able to use for lookup, you can create an associative array for each key. Associative arrays are generally implemented as hash maps, so lookup will be on the order of O(1). – Dan Jul 6 '16 at 16:07
1

I am not very sure about what you want from your question, but here are two methods I can think of, with the objectives to:

  1. provide optimum performance
  2. maintain flexibility through type abstraction

About your method: Why did you create the pageData class? Why couldn't you store them in a dynamic object/associative array? Then create an abstract method getTagType() in the FragmentBase abstract class, with implementations such as:

public function getTagType() : string{
    return "JS-FILES";
}

So you can, for example, store an object as $pageData[$fragment->getTagType()][] = $fragment;, then given the type from the HTML comment, search for the object from that array.

Another method: What about giving the fragments unique IDs? I cannot elaborate on this since I don't understand why you need to search for an instance from an array. Is there one corresponding object per fragment (HTML comment)? If that is the case, why not simply put the ID in the comment, then retrieve the object using the ID when you render the page? In this case, it gets even faster because direct numeric key to get from a single-dimensional array is always the fastest method to retrieve an element from an array.

Third method: I think this is really irrelevant with your case here. You can use an in-memory SQL database (such as new SQLite3(":memory:")) to create a table that indexes every object (every object needs a unique ID to be a placeholder in the table). Then you can easily use an SQL query to search from the many entries, more efficiently. However, I think that SQLite only improves performance when you are processing a really big amount of data (so that the time to prepare/parse statements is shorter than time for manually searching the data), especially when the data will retain for a long time (so not good for webpage-preprocessing PHP on HTTP servers) because the initialization of the database every time is time-consuming, and the data have to be really frequently reused so as to make the time for preparing statements negligible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.