Search code examples
phphtmltemplate-engine

What is the best way to insert HTML via PHP?


Talking from a 'best practice' point of view, what do you think is the best way to insert HTML using PHP. For the moment I use one of the following methods (mostly the latter), but I'm curious to know which you think is best.

<?php
  if($a){
?>
[SOME MARKUP]
<?php
  }
  else{
?>
[SOME OTHER MARKUP]
<?php
  }
?>

Opposed to:

<?php
  unset($out);
  if($a) $out = '[SOME MARKUP]';
  else $out = '[OTHER MARKUP]';
  print $out;
?>

Solution

  • If you are going to do things that way, you want to separate your logic and design, true.

    But you don't need to use Smarty to do this.

    Priority is about mindset. I have seen people do shocking things in Smarty, and it eventually turns into people developing sites in Smarty, and then some bright spark will decide they need to write a template engine in Smarty (Never underestimate the potential of a dumb idea).

    If you break your code into two parts and force yourself to adhere to a standard, then you'll get much better performance.

    PageLogic.php

    <?php 
    
      $pageData = (object)(array());  // Handy trick I learnt. 
    
      /* Logic Goes here */
    
    
     $pageData->foo = SomeValue; 
    
     ob_start(); 
     require("layout.php"); 
     ob_end_flush();
    

    Layout.php

     <html>
       <!-- etc -->
       <?php for ( $i = 1; $i < 10; $i++ ){ ?>
        <?php echo $pageData->foo[$i]; ?>
       <?php } ?>
       <!-- etc -->
    </html>
    

    PHP Was written as a templating engine, so you at least should try to use it for its designed task before assessing whether or not you need to delve into Smarty.


    Moreover, if you decide to use a templating engine, try get one that escapes HTML by default and you "opt out" instead of "opt in." You'll save yourself a lot of XSS headaches. Smarty is weak in this respect, and because of this, there are a lot of content-naïve templates written in it.

    {if $cond}
        {$dangerous_value}
    {else}
        {$equally_dangerous_value}
    {/if}
    

    Is generally how Smarty templates go. The problem is $dangerous_value can be arbitrary HTML and this just leads to even more bad coding practices with untraceable spaghetti code everywhere.

    Any template language you consider should cater to this concern. e.g.:

    {$code_gets_escaped} 
    {{$code_gets_escaped_as_a_uri}}
    {{{$dangerous_bare_code}}}
    

    This way, your potential doorways for exploitation are easily discernible in the template, as opposed to the doorway to exploitation being the DEFAULT behaviour.