Efficiently mixing PHP and HTML?

Is there a least verbose/most efficient way of changing multiple separate parts of HTML with one bit of PHP code? I mean, can you come out of the PHP tags without closing the function so that it doesn’t need to be repeated wherever the HTML needs to be changed in response to the same condition?

An example to show you what I want to do:

<li<?php/* check for error and print class name */?>>
	<label for="nameInput" id="nameLabel"><?php/* check for error and change label text or else print default text */?></label>
	<input type="text" name="name" id="nameInput" aria-labelledby="nameLabel" [...etc...] >
</li>

So if I used that, I would be repeating the same “if” function just to modify two bits of mark up: one to add a new class to the LI and one to change the label.

Yes, you can exit PHP during a command block and reenter it still inside the command block.

<?php if(true) { ?>
SomeHTML
<?php } ?>

It’ll be easier to read (and extend later) if you do the error-checking logic in it’s own php block, then just output the various values in the appropriate spots in the HTML…


<?php
    // check for error and store LI class name and input label
    if (someError()) {
        $classname = 'whatever';
        $label = 'Name';
    }
?>

<li class="<?=classname?>">
	<label for="nameInput" id="nameLabel"><?=$label?></label>
	<input type="text" name="name" id="nameInput" aria-labelledby="nameLabel" [...etc...] >
</li>

Thanks for replying.

StarLion: Just need to check… How would I write the print function into your snippet in a way that will print the multiple strings that I need to add?

Cholmon: Your method looks interesting, but how would it handle the addition of an “else” statement, as needed for the initial label text in my snippet? e.g. default text of “Name”, but error text of “Please edit your name” or something like that.

My advice: STOP OPENING AND CLOSING PHP FOR NO GOOD REASON… It’s called, echo, USE IT. (again though, I think <?php and ?> should be removed from the php specification ENTIRELY!)

and use some inline evaluations…

Though I think we’d really need to see what it is you actually have for code – we’re guessing wildly without knowing what it is you are checking for values or want the PHP to output.

Oh, and what’s with the LI around label/input pairings? They already have semantic meanings, you shouldn’t be slapping a new one on top of that.

Oh, and what’s with the LI around label/input pairings? They already have semantic meanings, you shouldn’t be slapping a new one on top of that.

Because it allows me to do what I need to do with the layout. Many times, I agree with you, but sometimes, I do wish that you would for once not moan about other people’s HTML.

And are you really suggesting that I should use echo to print out an entire HTML form? Surely, that’s not the best way? Otherwise, I would have seen that done at least once in a book. But I’ve never seen that.

But I’ll tell you what I’ll do. If you want to completely rewrite the PHP and HTML that I’ve worked hard on for ages, learning from zero as I go along, you’re welcome to do so. Genuine offer.

And what the hell are “inline evaluations” when they come home?

Yeah, you can put whatever logic you need in that first block…


<?php 
    // check for error and store LI class name and input label 
    if (someError()) { 
        $classname = 'whatever'; 
    } 

    // set the label here depending on the error check...or 
    // set the default value...or hit the database...or do a
    // jig...whatever you want. put all your complex logic here,
    // just set variables for what you plan on outputting.
    $label = someOtherErrorCheck() ? 'Error Label': 'Default Label';
?> 

<li class="<?=classname?>"> 
    <label for="nameInput" id="nameLabel"><?=$label?></label> 
    <input type="text" name="name" id="nameInput" aria-labelledby="nameLabel" [...etc...] > 
</li>

Using lists for form elements is something just about all leaders in the industry do. Besides, its nice to have that extra element for achieving certain design goals. I mean… a form is a list of form elements.

The best thing to do is do carry out as little logic as possible in templates. That is the best way to make them readable. Opening and closing tags isn’t a big deal. In fact most the time its more readable then printing pieces of HTML with echo. In some cases that can be a “better” approach but not always. Of course this comes more down to personal preference anyway.

There, fixed… Putting a list on that is no different than using tables for layout.

Well, when you put it that way it makes so much sense.

Thanks for replying, cholmon. That technique looks really tidy and maintainable.

Deathshadow: would you prefer it if I wrapped them in divs? Because whatever you say about semantics and “nimrods”, I couldn’t get the layout that I wanted without some parent block-level element around each label/input pair.

And in any case, that is completely orthogonal to the point of this thread.

Braceless syntax is easier to read here.


<?php if(true): ?>
some html
<?php endif ?>

What appearance were you aiming for? A simple BR should be all you need on them… maybe margin-bottom on the label… Worst case put the input inside the label… If you REALLY needed it (which I doubt) a DIV would be more appropriate as it does not add any semantic meaning to what it’s wrapping… as opposed to LI which does.

Still, do you have an example of the actual data you’re processing and values you are checking for? Everything above is all guesswork but it SOUNDS like you should either be using inline evaluations or switch/case instead of IF… all of the above posts being nothing more than wild guesses as you’ve not actually said what data you are outputting or what values you are checking for.

I ran a quick little test since deathshadow brought up the performance issue:

<?php 
$start_process = (float) array_sum(explode(' ',microtime()));

$variable1='1';
$variable2='2';
$variable3='3';
$variable4='4';
$variable5='5';

echo
   '<html><body><table><tr>
       <td>'.$variable1.'</td>
       <td>'.$variable2.'</td>
       <td>'.$variable3.'</td>
       <td>'.$variable4.'</td>
       <td>'.$variable5.'</td>
   </tr></table></body></html>';
   
$end_process = (float) array_sum(explode(' ',microtime()));

echo "<!--Execution time: ". sprintf("%.4f", ($end_process-$start_process))." seconds" . "-->";
?>

<?php 
$start_process = (float) array_sum(explode(' ',microtime()));

$variable1='1';
$variable2='2';
$variable3='3';
$variable4='4';
$variable5='5';

?>
<html><body><table><tr>
       <td><?php echo $variable1; ?></td>
       <td><?php echo $variable2; ?></td>
       <td><?php echo $variable3; ?></td>
       <td><?php echo $variable4; ?></td>
       <td><?php echo $variable5; ?></td>
</tr></table></body></html>
<?php   
$end_process = (float) array_sum(explode(' ',microtime()));

echo "<!--Execution time: ". sprintf("%.4f", ($end_process-$start_process))." seconds" . "-->";
?>

Result:

<html><body><table><tr>
       <td>1</td>
       <td>2</td>
       <td>3</td>
       <td>4</td>
       <td>5</td>
   </tr></table></body></html><!--Execution time: 0.0000 seconds-->

<html><body><table><tr>
       <td>1</td>
       <td>2</td>
       <td>3</td>
       <td>4</td>
       <td>5</td>
</tr></table></body></html>
<!--Execution time: 0.0000 seconds-->

Granted, it was a small example, but there wasn’t a measurable difference either way.

I tend to use the second method–mostly group all the HTML together and just plug in values with PHP. For more complicated operations, I plug in blocks of HTML.

I can’t say I’ve ever noticed a difference in performance going one way or the other. I just prefer the method with the most separation because it’s easier to read and you don’t have to deal with escape characters in echo statements.

Your test is flawed –

  1. network performance can skew the numbers either direction +/- 50% or more. Turn on buffering at the start to eliminate this.

ob_start();

  1. you don’t account for timer granularity – which for most systems running php is 18.2ms… so you should be testing for the timer rollover before starting your test.

  2. testing for a number of iterations with inaccurate (VERY inaccurate) timers is usually a bad idea – it’s better to test for a fixed period of time as the only place you can trust the time is at the rollover.


/* wait for tick change to reduce granularity bug */
$errorOffset=microtime(true);
while ($errorOffset==microtime(true)) {}
$finish=microtime(true)+3;

I’d then advise running the test for three seconds, which should on a reasonably fast server deliver around 300-500K iterations to compare against.

  1. The size of the buffer could also be interfering, and outputting enough iterations for any sort of test to matter would be MEGABYTES worth of data – so use

ob_clean();

after each test to clear out the buffer

  1. Are you running those back to back as a single file? code caching could be interfering making whichever one is second run faster… so make sure that’s two separate tests.

These are common enough mistakes when it comes to benchmarking PHP though. It’s not like the majority of PHP developers even learned about timer granularity.

If I were to test, it would go like this:


<?php 

$variable1='1';
$variable2='2';
$variable3='3';
$variable4='4';
$variable5='5';
 
ob_start(); // remove network output from interfering with test 

$count=0; 

/* wait for tick rollover to reduce granularity bug */
$errorOffset=microtime(true);
while ($errorOffset==microtime(true)) {}
$finish=microtime(true)+3;
?>

<?php while (microtime(true)<$finish): ?>
	<tr>
	 <th><?php echo $variable1; ?></th>
	 <td><?php echo $variable2; ?></td>
	 <td><?php echo $variable3; ?></td>
	 <td><?php echo $variable4; ?></td>
	 <td><?php echo $variable5; ?></td>
	</tr>
	<?php $count++; ?>
<?php endwhile ?>

<?php

ob_clean();

echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	lang="en"
	xml:lang="en"
><head>

<meta
	http-equiv="Content-Type"
	content="text/html; charset=utf-8"
/>

<meta
	http-equiv="Content-Language"
	content="en"
/>

<title>
	Echo vs. Opening and Closing PHP benchmark
</title>

</head><body>

<p>
	Iterations using <?php ?> : ',$count,'
</p>

</body></html>';

?>

and


<?php 

$variable1='1';
$variable2='2';
$variable3='3';
$variable4='4';
$variable5='5';
 
ob_start(); // remove network output from interfering with test 

$count=0;

/* wait for tick rollover to reduce granularity bug */
$errorOffset=microtime(true);
while ($errorOffset==microtime(true)) {}
$finish=microtime(true)+3;

while (microtime(true)<$finish) {
	echo '
	<tr>
		<th>',$variable1,'</th>
		<td>',$variable2,'</td>
		<td>',$variable3,'</td>
		<td>',$variable4,'</td>
		<td>',$variable5,'</td>
	</tr>';
	$count++;
}

ob_clean();

echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
	xmlns="http://www.w3.org/1999/xhtml"
	lang="en"
	xml:lang="en"
><head>

<meta
	http-equiv="Content-Type"
	content="text/html; charset=utf-8"
/>

<meta
	http-equiv="Content-Language"
	content="en"
/>

<title>
	Echo vs. Opening and Closing PHP benchmark
</title>

</head><body>

<p>
	Iterations using Echo : ',$count,'
</p>

</body></html>';

?>

After summing the results of 20 tests (which the results still fluctuate by 5% – probably due to server load) the average for <?php ?> was 591,362 and for echo without opening and closing php it came to 647,953. That’s almost 10% difference. 10% is pretty damned good especially since it’s cleaner code.

I mean, this fistfull of ugly:


<?php while (microtime(true)<$finish): ?>
	<tr>
	 <th><?php echo $variable1; ?></th>
	 <td><?php echo $variable2; ?></td>
	 <td><?php echo $variable3; ?></td>
	 <td><?php echo $variable4; ?></td>
	 <td><?php echo $variable5; ?></td>
	</tr>
	<?php $count++; ?>
<?php endwhile ?>

vs.


while (microtime(true)<$finish) {
	echo '
	<tr>
		<th>',$variable1,'</th>
		<td>',$variable2,'</td>
		<td>',$variable3,'</td>
		<td>',$variable4,'</td>
		<td>',$variable5,'</td>
	</tr>';
	$count++;
}

Shouldn’t even be a choice on cleanliness ALONE. Oh, and string addition using periods is slower than comma’s… don’t waste time having to build the full string in memory on top of the copy in the bytecode, when you can just dump the bytecoded copy at it. String addition should be reserved for when it’s NEEDED – like inside an inline evaluation. That’s why echo accepts comma delimited values in the first place.

But again, that’s where understanding how things work under the hood helps… I really think people should be forced to learn ASM before being allowed anywhere NEAR a high level language… and after 30 years of programming, MOST of the PHP code I look at just has me shaking my head going “don’t they teach these kids ANYTHING?”

Sure, it was…I never claimed it wasn’t. I slapped it together in 30 seconds. If I wanted to spend a few minutes on it and actually do a proper performance test, then yes, I would’ve pursued things more in the direction you took.

However, I do admit being unaware of how to adjust for timer inaccuracies.

Ugliness and cleanliness aside, also consider your editor’s syntax highlighter. Many editors will properly highlight both PHP and HTML within the same file, but only in the former case above, where such editors rely on the <?php ?> tags to tell when to switch syntax mode. The latter chunk of code will only be highlighted as PHP, since the HTML will simply be seen as string literals.

Plus, you don’t have to worry about escaping any quotes (and short tags make it a bit cleaner)…


<?php while (microtime(true) < $finish): ?>
	<tr>
	 <th><?=$variable1?></th>
	 <td><?=$variable2?></td>
	 <td><?=$variable3?></td>
	 <td><?=$variable4?></td>
	 <td><?=$variable5?></td>
	 <td>raw "HTML" in 'quotes', no escaping needed.</td>
	</tr>
	<?php $count++; ?>
<?php endwhile ?>

which is something I’ve been turning OFF in editors since it was introduced, as the conflicting color contrasts turn it into an illegible acid-trip for me. Hell, I used to have to copy/paste every time someone uses the color highlighting version of the CODE tag on these forums just to make it legible… until I finally neutered it with user CSS in Opera.

Screwy since I’m not color blind. It’s called ‘dialation issues’; when you have a hodge-podge of colors the eye cannot adjust to any of them at the same time – hence the code becomes illegible.

Never understood the appeal as for me it’s a step backwards in usability; but I say the same thing about tabs in editors, auto-completion, and all the other useless crutches that just get in my way… As I often say “Oh for Pete’s sake, just let me type the bloody thing!”; Actually, it’s a bit more profane than that.

Sounds like a medical issue… one that not everyone has, surprising I know.