skip to content

PHP: What happened with htmlspecialchars?

You may have noticed new errors relating to how single quotes are escaped after upgrading to PHP 8.1. What actually happened is that the default setting for htmlspecialchars has changed from the previous ENT_COMPAT to ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401.

Effect on htmlspecialchars()

While several functions are affected by this change, we are focusing here on htmlspecialchars which affects only characters that have special meaning in HTML. The idea being to escape special characters so they can be displayed in HTML without affecting HTML markup.

In the table below you can see that nothing has changed regarding double quotes or the less thean and greater than characters. Only single quotes are behaving differently:

ENT_COMPAT PHP 8.1 Default ENT_HTML5
" " " "
& & & &
< &lt; &lt; &lt;
> &gt; &gt; &gt;
' ' &#039; &apos;

Please note that wher we refer to ENT_HTML5 in the table above, and elsewhere, what we are actually using is a bitwise combination of ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5, a variation on the default flags.

So why does this matter?

Previously we have presented code for safely including PHP variables in JavaScript as follows:

<a href="#" onclick="return confirm('Are you sure you want to delete this item?\n<?PHP echo addslashes(htmlspecialchars($product)); ?>'); ?>">Delete Product</a>

So here we have a demonstration of the problem. In the first column you have the escaped string as it would display in HTML, while in the second column you have a button that triggers an 'alert' dialogue with the same text.

HTML Output alert()
ENT_COMPAT Mary\'s Lamb
PHP 8.1 Mary&#039;s Lamb
ENT_HTML5 Mary&apos;s Lamb

In most (all?) modern browsers only the first button will work and the others will fail with a JavaScript error. The issue being that the JavaScript interpreter treats both &#039; and &apos; as literal single quotes.

The error message in Safari is as follows:

SyntaxError: Unexpected identifier 's'. Expected ')' to end an argument list.

What's the Solution?

Unfortunately, at this time, while PHP has announced the change to the default flags as per PHP 8.1.0, there are no configuration options letting you set your own values or apply a global override.

So at this stage your best bet is to specify ENT_COMPAT wherever htmlspecialchars is being used to insert variables into JavaScript where they could be surrounded by single quotes.

Or to re-write those JavaScript components so they are not 'inline' to the HTML and variables can be enclosed instead inside double quotes. Neither of the new encodings will cause problems when contained inside double-quotes.

< PHP

Post your comment or question
top