views:

97

answers:

3

Hey!

So here at work we have a home grown templating system, that is light weight and works great for us so far.

The wall we're hitting is that we want to be able to loop over a template. The use case is something like search results. We are trying to think of ways that we could do this. We've come up with three ways right now. First is the good old storing the html inside the loop and then looping over it and using concat to put the variables into the html. The second way we thought up was including a file repeatedly. And the third way was to include the file once, use output buffereing to capture its output, add the text echo " to it, and then using eval on it. (My boss wanted us to come up with creative ways of doing it).

Well, I prefer the include repeatedly method, as it allows us to separate the html from the logic completely. The eval method also does this, but it seems a little more hackish. Well we did some time tests on this and found that having the html right inside the loop (method one) was the quickest, and that was followed by the eval method, and including multiple times came in last. Including was actually about 5-6 times slower than the eval method. (We included the file/evaluated the file 1000 times, and did that 100 times and averaged them to get our results).

Is there any way to speed up the multiple include? (It would appear that each time we do the include php is hitting the file system again.)

Or does anyone have a way of accomplishing this type of thing?

A: 

Cache the final page. What I mean is take all your "blocks" (loops, pieces, whatever you want to call them) and join them into one PHP file in your cache, and just include that from then on. That way you're only hitting the filesystem once per request instead of, say, 25 times.

musicfreak
A: 

Old question, I know.

Anyways, I would suggest having a simple for or foreach loop inside the template. There is nothing wrong with that. First, since looping through some presentation code is still presentation logic in my eyes (as this also makes it easier to change the output from, say, output in columns to output in rows - stupid example). Second, PHP is still a templating language. There is nothing wrong with using some simple control structures in a template. Using systems like Smartys is just adding another layer of abstraction (with another syntax to learn), that has much of the power of PHP (and thus creates quite a lot of overhead). That's nonsense in my eyes (on a sidenote: for me that is the inner-platform effect, an anti-pattern).

Franz
Its not a bad idea. What we actually ended up doing at work is using the built in DOM parser of php to load in the file and then use that to change the template for each use.The big problem is that we wanted to have very clean templates with minimal php in them (no control structures if we can get away with it) and maintain a high level of customizability, like being able to change it for each posting that occurs.
Boushley
+2  A: 

As your tests showed, the best way to optimize the script is to cycle over already included HTML code into your script.

The impact time comes from:

  • eval() calls the PHP parser to validate the code
  • include() uses disk access

Each include() then downgrades performance reading the disk of an unaltered file. To optimize this disk access will be then your eval() option:

  • include(): intial-parser + [disk-access + parser]*N loops;
  • eval(): initial-parser + disk-access + parser*N loops
  • inline HTML: initial-parser

To keep the code clean, you can create functions containing the HTML, use global variables, or a single Object or Array variable containing all the data needed to be displayed into your HTML, something like

function html_comment ($comment)
{
    //global $comment;

    ?>
    <div class="comment">
     <div class="author"><?php echo $comment['author'] ?></div>
     <div class="date"><?php echo $comment['date'] ?></div>
     <div class="date"><?php echo $comment['content'] ?></div>
    </div>
    <?php
}

...
foreach ($comments as $comment)
    html_comment($comment);
Ast Derek
Pretty well sums up our findings... having the function is a good idea. I was really hoping there was something clever we just hand't thought of, but I guess not.
Boushley
The next step, as seen in phpBB, is to compile common sections and save them into a cache, and update them after some mins or after a change. I think you've made a pretty good job with your timings
Ast Derek