With stuff like template literals in JavaScript and templating languages, like JSX, I’ve gotten used to wanting to write my HTML templates in one nice chunk and sprinkling in variables wherever I need them.
I had a situation where I needed to do that in “raw” PHP the other day, so I’m just documenting it here.
Say I have some data like…
$title = "The Title";
$desc = "Some information about this thing blah blah.";
$img = "/images/header.jpg";
But that data changes, or there might be multiple sets of it, and I want to be able to pass that data into a function and have it spit out some HTML. That way, it’s easy to change the template and have it affect everywhere that uses it.
I don’t want to sprinkle it into some HTML as a one-off. I’d rather have a function.
function echo_card($title = "Default Title", $desc = "Default Description", $img = "/images/fallback.jpg") {
echo "";
}
Rather than string-interpolate a bunch of HTML together, PHP has the HEREDOC syntax that is a smidge like JavaScript’s template literals.
function echo_card($title = "Default Title", $desc = "Default Description", $img = "/images/fallback.jpg") {
$html = <<<"EOT"
<div class="card">
<img src="$img" alt="">
<h2>$title</h2>
<p>$desc</p>
</div>
EOT;
echo $html;
}
Now I can call this function to echo an HTML template with my data.
echo_card($title, $desc, $img);
I found it a fairly comfortable way to work, without requiring any other libraries or anything.
Great to know. Thanks for writing about it!
Awesome, extremely useful for me, thanks and happy New year’s
Have you seriously written an article which promotes including unescaped literals into HTML markup? In (almost) 2020?!
Those templating engines exist for a reason, a very good one even – to provide security and convenience. What you have posted here is an example of how to write XSS vulnerable PHP almost a decade after everyone and their mothers (finally) learned how to do the opposite!
You should either delete it or do it properly (at which point you will find first hand why template engines exist)
Yeah! AND, I shipped it on a PRODUCTION website!!! The humanity!!!!
I didn’t want to use a templating engine. I have my reasons.
In my case, it’s not. It’s not taking user input. It’s not taking anything other than some strings I pass it with my own hand-written code, and I’m doing it just for ease of use. A simple abstraction.
But it is a fair point that XSS is worth mentioning, so I’ll update the post to reflect that.
You may want to consider using
htmlspecialchars()
at some point for variable output, to HTML-encode all characters. Otherwise characters like>
might ruin your template or might leave you vulnerable to HTML injection.It’s nice but that could be more useful: Place your templates in one folder like {TEMPLATE_DIR}/card.php and then include it with a function like template(‘card’, $atts).
The template function looks like this:
And the template file:
This way more realistic because most of the time you need some logic with your code and HEREDOC syntax could makes that hard.
By the way, if you still want to use that method, you should consider using only one $atts parameter so you can easily develop without thinking parameters orders and names. WordPress, for example, has many parameter named $depracated. You can prevent that using $atts arrays always, I think.
Echo a HEREDOC variable is a cool thing but is higly limited specially if you need to do some checking (if) based on the data you have, for example if you need to add a class or style based on the data you can not include an “if” or call a function inside a HEREDOC, but you can do it if you echo your html straight from the function:
function echo_card($title = “Default Title”, $desc = “Default Description”, $img = “/images/fallback.jpg”) {
?>
<img src="” alt=””>
<h2 >
<?
}
I have always done the following instead of using HEREDOC, is this incorrect or ill-advised in any way?
function whatever($var = 'default') {
?>
<div class="blah"><?= $var ?></div>
<?php
}
Hey! This is great! I’ve never seen the EOT method used like this before. Very clever!
There’s another way that I implement this that works great for my applications using only PHP.
Here’s an example:
Hello World!
<?php
}
This helps out big time with syntax highlighting in your applications and still outputs the html!
Please consider using ${variable} when using variables in heredoc. It’s easier to distinguish the variables in heredoc that way. :)
You could have directly outputted the HTML rather than using the memory overhead of a temporary variable.
Beware of the need to escape the variables contextually for where they are being output. In other words,
htmlspecialchars()
.I know I’m not the first to point it out, but it is really important. The values need to be escaped properly before they are output. Even if the variables are not from the user and can’t be modified by an attacker, it is still a bug to not escape them as they may contain special characters.
You should use
htmlspecialchars
(oresc_html
oresc_attr
for WordPress code). Unfortunately, this makes the whole thing look uglier, but that is PHP for you.PHP-CS can detect a lot of these problems automatically.
I don’t like this way of doing it as it forces people in charge with integration to modify this code – and leads sadly to some unexpected bugs. Instead why wouldn’t you use php function include with a combination of ob_start/ob_end. The advantages are that html + php is exported in another file.