22
\$\begingroup\$

library.php

My own HTML tag encoder that will print HTML codes according to the input.

<?php
    function tag($tagname, $content = NULL, array $properties = NULL)
    {
        $html = "<$tagname";

        if (!($properties === NULL))
        foreach ($properties as $name => $value) {
            $html .= " $name=\"$value\"";
        }

        $html .= ($content === NULL || $content == "") ? " />" : ">$content</$tagname>";

        return $html;
    }
?>

index.php

The test index.php file that will run the HTML encoder from the library.

<?php 
    require 'library.php';

    echo tag("head",
        tag("meta","",array("name"=>"title","content"=>"Test Print"))
    );
    echo tag("body",
        tag("div",tag("p","test print".tag("br")."test print"),array())
    );
?>

Output:

<head><meta name="title" content="Test Print" /></head><body><div><p>test print<br />test print</p></div></body>

Question:

Using this library will make my code more readable when adding more PHP code. Instead of this <div><?php $variable ?></div>, I can use this echo tag("div",$variable);, but the latter will definitely be longer compared to just typing HTML code.

Should I not create such function and stay with coding HTML?

\$\endgroup\$
2
  • \$\begingroup\$ I would just use the more readable one and put in a comment the smaller one, then on production versions I will uncomment them and minify the whole thing. And when tracking bugs or updating, I would use the original and after the changes, repeat the uncomment+minifing process \$\endgroup\$
    – ajax333221
    Commented Apr 13, 2012 at 19:40
  • \$\begingroup\$ I'd say you've written yourself a macro. \$\endgroup\$
    – hakre
    Commented Apr 17, 2012 at 9:53

4 Answers 4

16
\$\begingroup\$

You are on the right track, but echo is not the right tool for the job IMO.

Thinking about XML generally we can represent the data like this:

array('tag', $attributes, $children);

The nesting of child elements allows us to do this (children is either an array for a nested element, or a string for a simple text child).

array('div',
      array('class' => 'container'),
      array(array('span', array(), 'One'),
            array('span', array(), 'Two')));

Which represents:

<div class="container">
    <span>One</span>
    <span>Two</span>
</div>

Using XMLWriter we can write this structure without too much trouble. I do that here in my library. The output from XMLWriter is always indented correctly, regardless of the context a template should appear in.

This is a classic example of matching your data structure to the problem you are solving. By creating a tree to represent the X(HT)ML we can build components of the structure where they belong in our code, rather than being forced to get all of our echo statements in the correct order.

\$\endgroup\$
13
\$\begingroup\$

There are several advantages to sticking with HTML and embedded PHP:

  • You get appropriate syntax highlighting.
  • You can take advantage of code-completion.
  • The all-PHP method lacks proper indentation of HTML elements in the code and when rendered.
  • The file can be viewed (sort of) in a browser.
  • A designer can modify the HTML as long as they know how to recognize the embedded PHP tags.

That being said, using the PHP approach you can take care of proper HTML-escaping attribute values (though you didn't) in one place to enforce correct rules.

I built a few helper classes for generating image and article link elements for my current project from Image and ContentItem model objects. These classes have setter methods named for the attributes and pull reasonable values from the underlying model objects all while performing correct HTML-escaping. The majority of the page is HTML plus PHP, but these classes make embedding a link or image very easy:

<div>
    Here is a picture of the car:
    <br/>
    <?= $this->img($car->getImage())->alt($car->getDescription()) ?>
</div>
\$\endgroup\$
0
7
\$\begingroup\$

It is absolutely critical that you escape your content and property values using htmlentities(). Otherwise, you could end up with invalid output, or possibly an HTML injection vulnerability in the worst case. (You might be able to trust that the tag names and attribute names contain no special characters.)

\$\endgroup\$
4
\$\begingroup\$

If you want readable and easier code, consider using HAML. You don't have to close tags there and it will still be single presentation file, not in chunks as you suggest

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.