One of PHP's strengths that I like the most is its versatility as a prototyping language. While the venerable MVC and friends are important in a large project with a lifespan measured in years, sometimes you just need to jot up a quick utility script or internal tool. In these cases, PHP's global context and loose typing really shine as you can mash everything into one sloppy file to start with, then gradually refactor logic out into functions and includes.
That said, I've never liked mixing languages in the same file.
<h1><?php echo $header; ?></h1> scans pretty easily, but any more complicated than that and it gets pretty unreadable pretty quickly. It can also do a real number on syntax highlighters, which makes debugging a painful process.
For generating well-formed XML of any dialect, you can't get much more thorough than PHP's built-in DOM implementation but there's nothing concise about it, and I'm trying to be fast, here.
What I want is a way to quickly blast out some arbitrary (but valid!) HTML string in a keystroke-conscious fashion, so I turn to two of my favorite syntactic-sugar-enablers, __toString() and ArrayAccess.
I'm a big fan of PHP's magic __toString() method and use it liberally. Let's start our HTML toolkit at the bottom, with an Attribute class.
The delimiter handling makes it a little hairy, but it's still pretty straightforward. Of course, HTML attributes by themselves are kind of worthless, so let's add a container class using SPL's ArrayObject:
Okay, so this is a little cooler. Now we have a class that we can wrap around an array and get a properly-formatted HTML attribute string, like this:
Neat, but of course we have to take it all the way if we want it to be awesome:
I know it looks like a lot, but most of it is just setters and getters. We model the HTML tag as an object with a numerically-indexed array of content nodes and an associative array of Attributes. For extra fanciness, we implement ArrayAccess so we can access properties using nice concise array notation. All we need is a little late static binding magic to make it all sing:
Now all we have to do is extend NamedTag with classes named for the HTML tags we want to output:
And tra-la, we now have objects representing HTML elements which can simply be echoed (conveniently, all existing HTML tags are valid PHP classnames, though I would use this solution with a namespace whenever possible to avoid future reserved word collisions; plus I like the type hint the namespace provides):
Pretty easy on the fingers! Because every class is just treated as a string, we can even nest our tags:
Or simply concatenate our objects as though they were strings:
The ArrayAccess implementation allows us easy access to the object's properties, just like SimpleXML: