Page 1 of 1
Mixing PHP and HTML
Posted: Wed Jan 10, 2007 6:45 am
by Bill H
I'm sure this has been discussed many times, but I haven't been able to find any of the discussions on it so I'll ask for your forbearance. Please either discuss one more time or point me to some previous discussions.
Code: Select all
<INPUT name="Name" type="text" value="<?php echo stripslashes($Row['CompName']); ?>">
All well and good. Now add a few conditions, like jumping into <?php ?> mode to set a text color based on error conditions, type of record being displayed, etc. Upshot is it is beginning to look like the <?php ?> operators are appearing on about every second or third line.
At what point does it become better to just stay in php mode and echo all of the html instead of jumping in and out of the php mode?
Posted: Wed Jan 10, 2007 6:58 am
by CoderGoblin
This has been discussed before under Templating with people taking sides so this is only my take...
In general and at it's simplest I try to have the following.
Code: Select all
<?php
// here Logic
// Get row from database
$var1=stripslashes($Row['CompName'];
$var2="I dont know whatever';
?>
<html>
...
<INPUT name="Name" type="text" value="<?php echo $var1 ?>">
...
</html>
The top php block creates all the values to insert. Within the HTML you only echo variables. Not always that simple. You may want to look at Smarty Templates for further examples (although I don't use it).
Posted: Wed Jan 10, 2007 8:24 am
by Bill H
Yeah, I do that kind of thing, but consider the foillowing:
Code: Select all
<P>Contact Name </P>
<?php
if (isset($Qname)) echo "<H1>First:</H1>\n";
else echo "<P>First:</P>\n";
?>
<INPUT name="FirstName" type="text" class='forminp' style="width:150px" value="<?php echo stripslashes($Row['First']); ?>">
<?php
if (isset($Qname)) echo "<H1>Last:</H1>\n";
else echo "<P>Last:</P>\n";
?>
<INPUT name="LastName" type="text" class='forminp' style="width:150px" value="<?php echo stripslashes($Row['Last']); ?>">
<P>Address</P>
What's the effeciency of having a page full of this stuff? The post to the db does error checking and if entries are not with certain parameters rejects the entry and returns to the form with the same data and colors to indicate the error. So between the color display determinations and the data display, there's a lot of jumping in and out of mode.
That's just two data fields and I'm in and out of <?php ?> four times. That just seems ugly to me.
Posted: Wed Jan 10, 2007 9:10 am
by shiznatix
its not inefficient, its just hard to go back and make a design change or to have a designer come in and start editing the html. Look into a templating engine, I use phptal as its super easy to install and does not take long to learn.
Posted: Wed Jan 10, 2007 12:06 pm
by matthijs
It will never be perfect, but reducing duplicate code and going in and out of php makes a small difference
Code: Select all
<p>Contact Name </p>
<?php if (isset($Qname)) { ?>
<h1>First:</h1>
<h1>Last:</h1>
<?php } else { ?>
<p>First:</p>
<input name="FirstName" type="text" class='forminp' style="width:150px" value="<?php echo $Row['First']; ?>">
<p>Last:</[>
<input name="LastName" type="text" class='forminp' style="width:150px" value="<?php echo $Row['Last']; ?>">
<p>Address</p>
And also, why the stripslashes? That shouldn't be necessary.
Posted: Wed Jan 10, 2007 11:35 pm
by Bill H
I'm not sure I'm making my point. That snippit would in one case show the two labels in one color without the inputs and in the other case the labels in the other color with the inputs, which is hardly what I would want to achieve.
Let me try it this way. Which would be better?
Code: Select all
<?php
if (isset($Qname)) echo "<H1>First:</H1>\n";
else echo "<P>First:</P>\n";
?>
<INPUT name="FirstName" type="text" class='forminp' style="width:150px"
value="<?php echo $Row['First']; ?>">
<?php
if (isset($Qname)) echo "<H1>Last:</H1>\n";
else echo "<P>Last:</P>\n";
?>
<INPUT name="LastName" type="text" class='forminp' style="width:150px"
value="<?php echo $Row['Last']; ?>">
or
Code: Select all
<?php
if (isset($Qname)) echo "<H1>First:</H1>\n";
else echo "<P>First:</P>\n";
echo "<INPUT name='FirstName' type='text' class='forminp' style='width:150px' value=",$Row['First']),">";
if (isset($Qname)) echo "<H1>Last:</H1>\n";
else echo "<P>Last:</P>\n";
echo "<INPUT name='LastName' type='text' class='forminp' style='width:150px' value=",$Row['Last']),">";
?>
(The stripslashes() actually is needed since it may be reiterating a $_POST and magic_quotes_gpc is turned on, but for clarity here I removed it.)
Posted: Thu Jan 11, 2007 12:49 am
by matthijs
Well, how you format your code is a personal preference of course. Separating PHP and HTML is/can be a good thing. But I don't think that is always true. It'll depend on the specific code design what's the best.
For me, the most important "rule" is that it should be easy to understand. The code should be as readable as can be. That will reduce the chance of making mistakes.
I would rewrite your code like:
Code: Select all
<?php echo (isset($Qname)) ? "<H1>First:</H1>\n" : "<P>First:</P>\n" ; ?>
<INPUT name="FirstName" type="text" class='forminp' style="width:150px" value="<?php echo $Row['First']; ?>">
<?php echo (isset($Qname)) ? "<H1>First:</H1>\n" : "<P>First:</P>\n" ; ?>
<INPUT name="LastName" type="text" class='forminp' style="width:150px" value="<?php echo $Row['Last']; ?>">
That way, every single rule has one single piece of logic/ouput. I find that readable. But again, this is all up to your personal preference. I can imagine that if the code grows, you could take away the ternary style and use the if else blocks seperated over several lines to keep it readable.
Also, for the magic quotes issue: a good way of dealing with them is having a check at the entry of your code which checks if magic quotes is on, and if so, strips all extra slashes. There are several possibilities (search for "magic quotes normalization"), but I like this code from Ilia Alshanetsky's PHP Guide to PHP Security:
Code: Select all
/* Magic quotes normalization */
if (get_magic_quotes_gpc()) {
$input = array(&$_GET, &$_POST, &$_COOKIE, &$_ENV, &$_SERVER);
while (list($k,$v) = each($input)) {
foreach ($v as $key => $val) {
if (!is_array($val)) {
$input[$k][$key] = stripslashes($val);
continue;
}
$input[] =& $input[$k][$key];
}
}
unset($input);
}
Having this at the top of your script and you don't have to worry about stripslashes all over the place. Because what would you do if a slash in the input is actually wanted? Would you strip it and with that change the data? Probably not what you want.
Posted: Thu Jan 11, 2007 1:13 am
by Christopher
Bill H, it does not really matter if you mix HTML and PHP in templates. It is really a decision for the programmer/team to decide. Probably the most important thing is to make sure that the use of PHP as a template language is kept separate from when PHP is used as a traditional programming language. The reason is that it is easy for undesirable dependencies to sneak in when you glob everything together. I believe it is considered a best practice for the template/view code to get its data from something with a clearly defined interface.
Posted: Thu Jan 11, 2007 1:27 am
by Luke
yea it's fine as long as you know the difference between display logic and business logic, Typically that distinction is pretty simple to make, but there are times when it's questionable.
Posted: Thu Jan 11, 2007 3:07 am
by RobertGonzalez
I look into TemplateLite as a template engine. If not for the templating, then just to see the mash that the cached templates look like. Mash hashes of code/presentation are hard to read, harder to maintain and difficult to modify later on. I have been using templates for a long time now and I couldn't love them more.
Posted: Thu Jan 11, 2007 3:43 am
by matthijs
Everah wrote:I look into TemplateLite as a template engine. If not for the templating, then just to see the mash that the cached templates look like. Mash hashes of code/presentation are hard to read, harder to maintain and difficult to modify later on. I have been using templates for a long time now and I couldn't love them more.
I haven't worked with template lite yet. But what do you mean with this? First you say mash is difficult to read, then that you love them? Sorry if I misunderstood or for my complete ignorance

Posted: Thu Jan 11, 2007 5:05 am
by AKA Panama Jack
What he means is the compiled code looks like crap.
Here is an example of a javascript section in a template that is using smarty/template lite markup...
Code: Select all
{if $query_debug == true }
<SCRIPT language=javascript>
_query_debug_console = window.open("","Query Debug","width=750,height=600,resizable,scrollbars=yes");
_query_debug_console.document.write("<HTML><TITLE>Query Debug Console</TITLE><BODY onload='self.focus();' bgcolor=#ffffff>");
_query_debug_console.document.write("<table border=0 width=100%>");
_query_debug_console.document.write("<tr bgcolor=#cccccc><th colspan=2>Query Debug Console</th></tr>");
_query_debug_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>Included page queries (load time in seconds):</b></td></tr>");
{foreach key=key value=sql from=$query_list}
_query_debug_console.document.write("<tr bgcolor={if $key % 2}#eeeeee{else}#fafafa{/if}>");
_query_debug_console.document.write('<td width="75%">{$query_list[$key]|strip|addslashes }<hr><font color=\"red\"><b>{$query_list_errors[$key]|strip|addslashes}</b></font></td>');
_query_debug_console.document.write("<td width=\"25%\"><font color=\"red\"><b><i>({$query_list_time[$key]|string_format:"%.5f"} seconds)</i></b></font></td></tr>");
{/foreach}
_query_debug_console.document.write("</table>");
_query_debug_console.document.write("</BODY></HTML>");
_query_debug_console.document.close();
</SCRIPT>
{/if}
Here is what the compiled php output looks like...
Code: Select all
<?php if ($this->_vars['query_debug'] == true): ?>
<SCRIPT language=javascript>
_query_debug_console = window.open("","Query Debug","width=750,height=600,resizable,scrollbars=yes");
_query_debug_console.document.write("<HTML><TITLE>Query Debug Console</TITLE><BODY onload='self.focus();' bgcolor=#ffffff>");
_query_debug_console.document.write("<table border=0 width=100%>");
_query_debug_console.document.write("<tr bgcolor=#cccccc><th colspan=2>Query Debug Console</th></tr>");
_query_debug_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>Included page queries (load time in seconds):</b></td></tr>");
<?php if (count((array)$this->_vars['query_list'])): foreach ((array)$this->_vars['query_list'] as $this->_vars['key'] => $this->_vars['sql']): ?>
_query_debug_console.document.write("<tr bgcolor=<?php if ($this->_vars['key'] % 2): ?>#eeeeee<?php else: ?>#fafafa<?php endif; ?>>");
_query_debug_console.document.write('<td width="75%"><?php echo $this->_run_modifier($this->_run_modifier($this->_vars['query_list'][$this->_vars['key']], 'strip', 'plugin', 1), 'addslashes', 'PHP', 1); ?>
<hr><font color=\"red\"><b><?php echo $this->_run_modifier($this->_run_modifier($this->_vars['query_list_errors'][$this->_vars['key']], 'strip', 'plugin', 1), 'addslashes', 'PHP', 1); ?>
</b></font></td>');
_query_debug_console.document.write("<td width=\"25%\"><font color=\"red\"><b><i>(<?php echo $this->_run_modifier($this->_vars['query_list_time'][$this->_vars['key']], 'string_format', 'plugin', 1, "%.5f"); ?>
seconds)</i></b></font></td></tr>");
<?php endforeach; endif; ?>
_query_debug_console.document.write("</table>");
_query_debug_console.document.write("</BODY></HTML>");
_query_debug_console.document.close();
</SCRIPT>
<?php endif; ?>
Just a tad harder to understand.

It kind of gives an example for how template languages make things more readable. I know it's not the best example but hey it is 5am here. :p
Here is maybe a better example...
Code: Select all
<table border="0" align="center">
<tr>
{if $total_signupclosed != $totalgames && $total_closed != $totalgames}
<td width="255">
<a id="newplayer" href="new_player.php"><img border="0" src="templates/{$templatename}images/newplayer.gif" align="left"></a>
</td>
{/if}
{if $total_closed != $totalgames}
<td width="134">
<input type="image" name="login" src="templates/{$templatename}images/login.gif" value="{$l_login_title}">
</td>
{/if}
</tr>
</table>
Compiled...
Code: Select all
<table border="0" align="center">
<tr>
<?php if ($this->_vars['total_signupclosed'] != $this->_vars['totalgames'] && $this->_vars['total_closed'] != $this->_vars['totalgames']): ?>
<td width="255">
<a id="newplayer" href="new_player.php"><img border="0" src="templates/<?php echo $this->_vars['templatename']; ?>
images/newplayer.gif" align="left"></a>
</td>
<?php endif; ?>
<?php if ($this->_vars['total_closed'] != $this->_vars['totalgames']): ?>
<td width="134">
<input type="image" name="login" src="templates/<?php echo $this->_vars['templatename']; ?>
images/login.gif" value="<?php echo $this->_vars['l_login_title']; ?>
">
</td>
<?php endif; ?>
</tr>
</table>
Posted: Thu Jan 11, 2007 5:10 am
by matthijs
Aha! Thanks for the explanation.
Posted: Thu Jan 11, 2007 7:27 am
by Bill H
The reason is that it is easy for undesirable dependencies to sneak in when you glob everything together.
I think this is what I'm trying to learn more about. Could you develop that thought a little bit? Examples, maybe?
Posted: Thu Jan 11, 2007 9:21 am
by matthijs
There are many discussions on the MVC pattern in the
theory and design forum, I would definitely read those.