Mixing PHP and HTML

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Bill H
DevNet Resident
Posts: 1136
Joined: Sat Jun 01, 2002 10:16 am
Location: San Diego CA
Contact:

Mixing PHP and HTML

Post 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?
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post 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).
User avatar
Bill H
DevNet Resident
Posts: 1136
Joined: Sat Jun 01, 2002 10:16 am
Location: San Diego CA
Contact:

Post 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.
User avatar
shiznatix
DevNet Master
Posts: 2745
Joined: Tue Dec 28, 2004 5:57 pm
Location: Tallinn, Estonia
Contact:

Post 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.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post 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.
User avatar
Bill H
DevNet Resident
Posts: 1136
Joined: Sat Jun 01, 2002 10:16 am
Location: San Diego CA
Contact:

Post 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.)
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post 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.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post 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.
(#10850)
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post 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.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post 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.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post 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 ;)
User avatar
AKA Panama Jack
Forum Regular
Posts: 878
Joined: Mon Nov 14, 2005 4:21 pm

Post 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>
Last edited by AKA Panama Jack on Thu Jan 11, 2007 5:14 am, edited 1 time in total.
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

Aha! Thanks for the explanation.
User avatar
Bill H
DevNet Resident
Posts: 1136
Joined: Sat Jun 01, 2002 10:16 am
Location: San Diego CA
Contact:

Post 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?
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

There are many discussions on the MVC pattern in the theory and design forum, I would definitely read those.
Post Reply