Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make php loop a template file efficiently

Tags:

php

I found a question on stack overflow about loading a template file in php, which was fine, but I wish to loop a template file of one line, many times instead. The article I have read is here [PHP Content Separation. The best answer on that page was from prodigitalson with his function GetTemplate.

Now I wanted to use something like this, but if I put his function in a loop then it wouldn't be very efficient, as it would keep loading the same file many times.

So I tried this. I would get the html included. Then store it in a variable, before putting it in the loop. However it didn't work.

Here is my code. The data is already in an array called $result.

$salesTemp=$this->tempLine('salesTEM.php');
while($row = array_shift($result)):
    echo $salesTemp;
endwhile;

private function tempLine($file){
    ob_start();
    require $file;
    return ob_get_clean();
}

The problem is that my variable is not being updated in the template. Here is my template

<li class="list-group-item"><?php echo $Customer;?><span class="label label-primary pull-right">SALES</span></li>

So is there a way of re-writing this so my $Customer variable is updated.

I am doing this to try to keep php and html separate.

like image 845
Thomas Williams Avatar asked Jan 18 '26 04:01

Thomas Williams


1 Answers

The primary problem I see with the code as it stands is that when $salesTemp is declared and ran through the tempLine() method, a string is returned (due to ob_get_clean()). The variable within the template has been resolved, and when the string is echoed in the loop the variables in the template are not updated because they have already been resolved and processed into a string. To fix the situation I would:

while ($row = array_shift($result)) {

    echo $this->tempLine('salesTEM.php', $Customer);
}

/**
 * @return string
 */
private function tempLine($file, $Customer) {

    ob_start();
    require $file;
    return ob_get_clean();
}

This would be the shortest path to getting what you want. If you wish to not include the template on each iteration, try:

$salesTEM = include 'salesTEM.php';

while ($row = array_shift($result)) {

    echo sprintf($salesTEM, $Customer);
}

/**
 * salesTEM.php
 */
<li class="list-group-item">
    %s
    <span class="label label-primary pull-right">SALES</span>
</li>

There are many frameworks available that provide this functionality out of the box and may be perused for additional information on templating techniques. Essentially, it is always good form to pass the information in via the function (file name and data) and expect the string back out. It will make it easy to unit test as well. Allowing it to pick up the information passively tends to make the code error prone, for example:

while ($row = array_shift($result)) {

    echo include 'salesTEM.php';
}

/**
 * salesTEM.php
 */
<li class="list-group-item">
    <?php echo $Customer;?>
    <span class="label label-primary pull-right">SALES</span>
</li>

You could accidentally include the file and have not declared the $Customer variable resulting in a difficult to find bug. Define everything going in and coming out and it will make it much more manageable down the road.

like image 167
Curtis Kelsey Avatar answered Jan 19 '26 19:01

Curtis Kelsey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!