PHPKonf 2025 Baku

htmlspecialchars

(PHP 4, PHP 5, PHP 7, PHP 8)

htmlspecialcharsConvertit les caractères spéciaux en entités HTML

Description

htmlspecialchars(
    string $string,
    int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
    ?string $encoding = null,
    bool $double_encode = true
): string

Certains caractères ont des significations spéciales en HTML, et doivent être remplacés par des entités HTML pour conserver leurs significations. Cette fonction retourne une chaîne de caractères avec ces modifications. Si vous avez besoin que toutes les sous-chaînes en entrée qui sont associées à des entités nommées soient transformées, utilisez la fonction htmlentities().

Si la chaîne en entrée passée à cette fonction et le document final partagent le même jeu de caractères, cette fonction est suffisante pour préparer l'entrée pour une inclusion dans la plupart des contextes d'un document HTML. Si cependant, l'entrée peut présenter des caractères qui ne sont pas codés dans le jeu de caractères du document final, et que vous souhaitez épargner ces caractères (comme des numériques ou des entités nommés), cette fonction et la fonction htmlentities() (qui n'encodes que les sous-chaînes qui ont des entités nommés équivalentes) ne sont pas suffisantes. Vous devez utiliser la fonction mb_encode_numericentity() à la place.

Remplacement effectué
Caractère Remplacement
& (ET commercial) &
" (double guillement) " sauf si ENT_NOQUOTES
' (simple guillemet) ' (pour ENT_HTML401) ou ' (pour ENT_XML1, ENT_XHTML ou ENT_HTML5), mais seulement lorsque ENT_QUOTES est défini
< (inférieur à) &lt;
> (supérieur à) &gt;

Liste de paramètres

string

La chaîne à convertir.

flags

Un masque bit d'un ou plusieurs drapeaux suivants, qui déterminent la façon dont les guillemets seront gérés, dont les séquences de code invalide seront gérées ainsi que le type du document utilisé. Par défaut, c'est ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401.

Constantes disponibles pour flags
Constante Description
ENT_COMPAT Convertit les guillemets doubles, et ignore les guillemets simples.
ENT_QUOTES Convertit les guillemets doubles et les guillemets simples.
ENT_NOQUOTES Ignore les guillemets doubles et les guillemets simples.
ENT_IGNORE Ignore les séquences de caractères invalides plutôt que de retourner une chaine vide. L'utilisation de ce drapeau est fortement déconseillé pour des » raisons de sécurité.
ENT_SUBSTITUTE Remplace les séquences de code invalide avec un caractère de remplacement Unicode U+FFFD (UTF-8) ou &#xFFFD; (sinon) au lieu de retourner une chaîne vide.
ENT_DISALLOWED Remplace les points du code invalides du document fourni avec un caractère de remplacement Unicode U+FFFD (UTF-8) ou &#xFFFD; (sinon) au lieu de le laisser tel quel. Ceci peut être utile pour, par exemple, s'assurer du bon formatage de documents XML contenant du contenu externe.
ENT_HTML401 Gère le code comme étant du HTML 4.01.
ENT_XML1 Gère le code comme étant du XML 1.
ENT_XHTML Gère le code comme étant du XHTML.
ENT_HTML5 Gère le code comme étant du HTML 5.

encoding

Un argument optionnel définissant l'encodage utilisé lors de la conversion des caractères.

Si omis, la valeur par défaut du paramètre encoding est la valeur de l'option de configuration default_charset.

Malgré le fait que cet argument soit techniquement optionnel, vous êtes vivement encouragé à spécifier la valeur correcte pour votre code si l'option de configuration default_charset a été définie de façon incorrecte pour l'entrée fournie.

Pour cette fonction, les encodages ISO-8859-1, ISO-8859-15, UTF-8, cp866, cp1251, cp1252, et KOI8-R sont équivalents, à condition que le paramètre string soit valable pour l'encodage, dans le sens où les caractères affectés par la fonction htmlspecialchars() occupent la même position dans tous ces encodages.

Les jeux de caractères suivants sont supportés :

Jeux de caractères supportés
Jeux de caractères Alias Description
ISO-8859-1 ISO8859-1 Europe occidentale, Latin-1.
ISO-8859-5 ISO8859-5 Jeu de caractère cyrillique rarement utilisé (Latin/Cyrillic).
ISO-8859-15 ISO8859-15 Europe occidentale, Latin-9. Dispose du signe Euro, des caractères spéciaux français et finlandais, qui manquent au Latin-1 (ISO-8859-1).
UTF-8   Unicode 8 bits multioctets, compatible avec l'ASCII
cp866 ibm866, 866 Jeu de caractères Cyrillique spécifique à DOS.
cp1251 Windows-1251, win-1251, 1251 Jeu de caractères Cyrillic spécifique à Windows.
cp1252 Windows-1252, 1252 Jeu de caractères spécifique de Windows pour l'Europe occidentale.
KOI8-R koi8-ru, koi8r Russe.
BIG5 950 Chinois traditionnel, principalement utilisé à Taïwan.
GB2312 936 Chinois simplifié, officiel.
BIG5-HKSCS   Big5 avec les extensions de Hong Kong, chinois traditionnel.
Shift_JIS SJIS, SJIS-win, cp932, 932 Japonais
EUC-JP EUCJP, eucJP-win Japonais
MacRoman   Jeu de caractères utilisé par Mac OS.
''   Une chaîne vide active la détection de l'encodage depuis un script (multioctet Zend), default_charset et la locale courante (voir nl_langinfo() et setlocale()), dans cet ordre. Non recommandé.

Note: Les autres jeux de caractères ne sont pas reconnus. L'encodage par défaut sera utilisé à la place et une alerte sera émise.

double_encode

Lorsque le paramètre double_encode est désactivé, PHP n'encodera pas les entités html existants ; par défaut, tout est converti.

Valeurs de retour

La chaîne convertie.

Si la chaîne d'entrée string contient une séquence de code invalide dans le paramètre encoding fourni, une chaîne vide sera retournée à moins que le drapeau ENT_IGNORE ou ENT_SUBSTITUTE ne soit défini.

Historique

Version Description
8.1.0 flags à changé de ENT_COMPAT à ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401.

Exemples

Exemple #1 Exemple avec htmlspecialchars()

<?php
$new
= htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
echo
$new; // &lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;
?>

Notes

Note:

Notez que cette fonction ne fait aucun autre remplacement que ceux qui sont listés ci-dessus. Pour faire un remplacement total, voyez plutôt htmlentities().

Note:

Dans le cas d'une valeur ambigue pour flags, les règles suivantes s'appliquent :

Voir aussi

add a note

User Contributed Notes 20 notes

up
64
Dave
12 years ago
As of PHP 5.4 they changed default encoding from "ISO-8859-1" to "UTF-8". So if you get null from htmlspecialchars or htmlentities

where you have only set
<?php
echo htmlspecialchars($string);
echo
htmlentities($string);
?>

you can fix it by
<?php
echo htmlspecialchars($string, ENT_COMPAT,'ISO-8859-1', true);
echo
htmlentities($string, ENT_COMPAT,'ISO-8859-1', true);
?>

On linux you can find the scripts you need to fix by

grep -Rl "htmlspecialchars\\|htmlentities" /path/to/php/scripts/
up
47
Mike Robinson
12 years ago
Unfortunately, as far as I can tell, the PHP devs did not provide ANY way to set the default encoding used by htmlspecialchars() or htmlentities(), even though they changed the default encoding in PHP 5.4 (*golf clap for PHP devs*). To save someone the time of trying it, this does not work:

<?php
ini_set
('default_charset', $charset); // doesn't work.
?>

Unfortunately, the only way to not have to explicitly provide the second and third parameter every single time this function is called (which gets extremely tedious) is to write your own function as a wrapper:

<?php
define
('CHARSET', 'ISO-8859-1');
define('REPLACE_FLAGS', ENT_COMPAT | ENT_XHTML);

function
html($string) {
return
htmlspecialchars($string, REPLACE_FLAGS, CHARSET);
}

echo
html("ñ"); // works
?>

You can do the same for htmlentities()
up
21
Kenneth Kin Lum
16 years ago
if your goal is just to protect your page from Cross Site Scripting (XSS) attack, or just to show HTML tags on a web page (showing <body> on the page, for example), then using htmlspecialchars() is good enough and better than using htmlentities(). A minor point is htmlspecialchars() is faster than htmlentities(). A more important point is, when we use htmlspecialchars($s) in our code, it is automatically compatible with UTF-8 string. Otherwise, if we use htmlentities($s), and there happens to be foreign characters in the string $s in UTF-8 encoding, then htmlentities() is going to mess it up, as it modifies the byte 0x80 to 0xFF in the string to entities like &eacute;. (unless you specifically provide a second argument and a third argument to htmlentities(), with the third argument being "UTF-8").

The reason htmlspecialchars($s) already works with UTF-8 string is that, it changes bytes that are in the range 0x00 to 0x7F to &lt; etc, while leaving bytes in the range 0x80 to 0xFF unchanged. We may wonder whether htmlspecialchars() may accidentally change any byte in a 2 to 4 byte UTF-8 character to &lt; etc. The answer is, it won't. When a UTF-8 character is 2 to 4 bytes long, all the bytes in this character is in the 0x80 to 0xFF range. None can be in the 0x00 to 0x7F range. When a UTF-8 character is 1 byte long, it is just the same as ASCII, which is 7 bit, from 0x00 to 0x7F. As a result, when a UTF-8 character is 1 byte long, htmlspecialchars($s) will do its job, and when the UTF-8 character is 2 to 4 bytes long, htmlspecialchars($s) will just pass those bytes unchanged. So htmlspecialchars($s) will do the same job no matter whether $s is in ASCII, ISO-8859-1 (Latin-1), or UTF-8.
up
25
Thomasvdbulk at gmail dot com
14 years ago
i searched for a while for a script, that could see the difference between an html tag and just < and > placed in the text,
the reason is that i recieve text from a database,
wich is inserted by an html form, and contains text and html tags,
the text can contain < and >, so does the tags,
with htmlspecialchars you can validate your text to XHTML,
but you'll also change the tags, like <b> to &lt;b&gt;,
so i needed a script that could see the difference between those two...
but i couldn't find one so i made my own one,
i havent fully tested it, but the parts i tested worked perfect!
just for people that were searching for something like this,
it may looks big, could be done easier, but it works for me, so im happy.

<?php
function fixtags($text){
$text = htmlspecialchars($text);
$text = preg_replace("/=/", "=\"\"", $text);
$text = preg_replace("/&quot;/", "&quot;\"", $text);
$tags = "/&lt;(\/|)(\w*)(\ |)(\w*)([\\\=]*)(?|(\")\"&quot;\"|)(?|(.*)?&quot;(\")|)([\ ]?)(\/|)&gt;/i";
$replacement = "<$1$2$3$4$5$6$7$8$9$10>";
$text = preg_replace($tags, $replacement, $text);
$text = preg_replace("/=\"\"/", "=", $text);
return
$text;
}
?>

an example:

<?php
$string
= "
this is smaller < than this<br />
this is greater > than this<br />
this is the same = as this<br />
<a href=\"http://www.example.com/example.php?test=test\">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc..."
;
echo
fixtags($string);
?>

will echo:
this is smaller &lt; than this<br />
this is greater &gt; than this<br />
this is the same = as this<br />
<a href="http://www.example.com/example.php?test=test">This is a link</a><br />
<b>Bold</b> <i>italic</i> etc...

I hope its helpfull!!
up
7
Daniel Klein
3 years ago
Because the documentation says

int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

you would think that ENT_HTML401 is important. But as the notes mention, ENT_HTML401 is the default if you don't specify the doc type. This is because ENT_HTML401 === 0. So

int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

is exactly equivalent to

int $flags = ENT_QUOTES | ENT_SUBSTITUTE
up
12
Felix D.
11 years ago
Another thing important to mention is that
htmlspecialchars(NULL)
returnes an empty string and not NULL!
up
11
ivan at lutrov dot com
14 years ago
Be careful, the "charset" argument IS case sensitive. This is counter-intuitive and serves no practical purpose because the HTML spec actually has the opposite.
up
5
qshing1437 at hotmail dot com
6 years ago
If you use htmlspecialchars() to escape any HTML attribute, make sure use double quote instead of single quote for the attribute.

For Example,

> Wrap with Single Quote
<?php
echo "<p title='" . htmlspecialchars("Hello\"s\'world") . "'">

// title will end up Hello"s\ and rest of the text after single quote will be cut off.
?>

> Wrap wi