Output escaping happens when you tell your PHP script to output some content, usually to a web page, but also to other servers, or XML files, or even the command-line. Every kind of output needs to be escaped differently, which means PHP never does it automatically. So you need to learn what escaping is, and how, when, and why to do it.
Why escape output?
The short answer is that if you don’t, unexpected things can happen, and a lot
of those things are either bad, or very bad indeed.
For a longer answer, you need to know more about the principle of what you’re
doing. I’ll use HTML as an example, because it’s the most common case and it’s
pretty straightforward to explain.
An HTML document contains plain text and tags. Tags are commands that tell a
browser to mark up a section of text, or insert, say, an image, or a button.
The document contains both at the same time, all written in plain text. To do
that, the HTML standard reserves some characters, most importantly:
&. When a browser sees a
by some letters, it thinks “great, time to show another picture of a kitten”.
But what if you want to show a
< in your text? Well, HTML has simple commands
called ‘entities’ that let you show any character without your web browser
mistaking them for commands. In this case, the entity for
the process of writing one as the other is known as escaping.
So when you’ve got someone’s name from them with your clever script and you
want to put it in your web page so that it says, “Hey Matt, how’s it going?”,
what you’re intending to do is send plain text, not commands. That means you
have to turn all the command characters in that text (like
HTML entities (like
>). And that’s what output escaping is.
If you don’t do it, someone with unusual parents might be called
<script, and your simple
greeting just turned into what’s known as a Cross-Site Scripting (XSS) attack.
XSS attacks happen when you fail to escape your output, and an attacker gets to
browsers. It can do anything from ruin your layout, to embedding adverts, to
stealing personal data like passwords. Sophisticated attackers can even take
over your site by making privileged users do things with their login without
Output escaping stops this happening by making sure that you never send
commands (HTML) when you only mean to send plain text. Along with filtering
input, it’s one of the standard procedures that every coder needs to use almost
By the way…
Escaping handles output, but you also need to filter to make sure you’re only accepting what you expect. I’ve written a separate article about that here, but the principle is that if you’re expecting a number, throw out everything that isn’t a number, and if you’re expecting a name, throw out everything that looks like HTML. Using both input filtering and output escaping gives you a defence in depth that protects your code, your server, and your site visitors. Read more…
When to escape your output
Generally, the best time to escape your output is as you’re displaying it. This
is because the kind of escaping you need to do depends on what you’re
displaying and where. As a trivial example, say you have a form where someone
fills in their name, and then you save it to your database and then show it on
screen. You need to escape separately and differently for both uses, and if you
escape too soon, you’ll end up making mistakes like double-escaping.
Another good reason to apply escaping as you’re displaying is that it’s much
easier to tell that you haven’t done it yet. Instead of having to look back
through all your scripts, you only have to look at the template ones.
And finally, leaving the output escaping to your templates makes it much easier
to reuse your code. For example you can reuse the same bit of code that asks
the database for a blog entry for your web page when making an RSS feed,
without having to change it. The less code you have to write, the less can go
wrong with it.
How to escape your output
Output plain text to a web page
When you’re doing this, what you need to make sure of is that you don’t let any
of your text get mistaken for HTML. So all you need to do is turn
&. Fortunately there’s a nice little
command that does this for you:
Output plain text into an HTML tag
Perhaps the most common example of this is when you’re filling in a form for
someone, so I’ll use that as an example.
If you’re mildly obsessive like me, and you only ever use double-quotes
your HTML tags, then you can use
ENT_COMPAT instead of
By the way…
This is why you should avoid using
print() to produce HTML like
<?php print "<b>Hi $name</b>"; ?>. When your commands and your variables are all mixed up like that, it’s really hard to get output escaping right! If you find yourself doing this a lot, think about using a template language instead. I recommend Twig, but there are dozens of alternatives.
Output HTML to a web page
The real problem here is that you can’t actually do any escaping – you’re actually trying to print commands to the browser. Instead, you have to rely on filtering to make sure that you only allow good HTML through. Filtering HTML is a big topic, but there’s a brief description of it on my PHP Filtering article. Don’t think you can tackle this problem without a lot of knowledge though; it’s much, much safer to use a filtering script that someone’s already written, something like htmLawed or HTMLPurifier.
If you’re using a library or tool to generate XML (e.g. PHP’s SimpleXML,
DOMDocument, or XMLWriter extensions), it should handle output escaping for
you. If you’re crazy enough to write it by hand, the good news is that you can
htmlspecialchars() exactly like in the HTML instructions above.
htmlentities() though, because XML only has about 6 entities by
default, and you’ll get a tonne of validation errors if you try to write things
Talking to a database
The syntax for escaping when talking to a database depends on the database
itself. For example mysql’s default is that you need to put a
\ in front of
', but MS SQL Server’s default is that you need to put two
single-quotes together like
'' if you mean to show one. Every database driver
in PHP has a way of doing this for you. Never ever use
won’t do what you think it does, and your database will be vulnerable to attack
(which in some cases means your whole server is vulnerable).
There’s a much better alternative to output escaping when it comes to
databases. It’s called a prepared statement. What you do is write your SQL with
placeholders where the data should go. PHP then sends the statement through one
channel (which only allows commands), and the data through another (which never
allows commands). Using prepared statements means you don’t have to worry about
escaping, and it guarantees that no one can do what’s known as an SQL injection
Most databases now offer this, and the easiest way to take advantage of them in
PHP is by using the built-in PDO extension. I’ve written a little more about
Other times you need to do output escaping
- Sending email
json_encode()isn’t really made to do this).
- Making JSON (PHP 5.2’s
json_encode()was made to do this, but again be careful, it can be fooled, and if your JSON contains HTML to be displayed, remember to escape it separately with
- Almost everywhere else!