PHPのお勉強!

PHP TOP

htmlentities

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

htmlentities適用可能な文字を全て HTML エンティティに変換する

説明

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

この関数はhtmlspecialchars()と同じですが、 HTML エンティティと等価な意味を有する文字をHTMLエンティティに変換します。 指定する flags 定数に応じて使われる変換テーブルを得るには、 get_html_translation_table() を使います。

もしデコード (逆の処理) をしたい場合、 html_entity_decode() を使用することができます。

パラメータ

string

入力文字列。

flags

以下のフラグを組み合わせたビットマスクです。 クォートや無効な符号単位シーケンス、そして文書型の扱いを指定します。 デフォルトは ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 です。

利用可能な flags 定数
定数名 説明
ENT_COMPAT ダブルクオートは変換しますがシングルクオートは変換しません。
ENT_QUOTES シングルクオートとダブルクオートを共に変換します。
ENT_NOQUOTES シングルクオートとダブルクオートは共に変換されません。
ENT_IGNORE 無効な符号単位シーケンスを含む文字列を渡したときに、 空の文字列を返すのではなく無効な部分を切り捨てるようになります。 このフラグは使わないようにしましょう。 » セキュリティの問題が発生する可能性があります
ENT_SUBSTITUTE 無効な符号単位シーケンスを含む文字列を渡したときに、 空の文字列を返すのではなく Unicode の置換文字に置き換えます。 UTF-8 の場合は U+FFFD、それ以外の場合は &#FFFD; となります。
ENT_DISALLOWED 指定した文書型において無効な符号位置を、Unicode の代替文字である U+FFFD (UTF-8) あるいは &#FFFD; で置き換えます。 これを設定しなければ、無効な符号位置をそのまま残します。 これは、外部コンテンツを埋め込んだ XML 文書を整形式に保つために有用です。
ENT_HTML401 コードを HTML 4.01 として処理します。
ENT_XML1 コードを XML 1 として処理します。
ENT_XHTML コードを XHTML として処理します。
ENT_HTML5 コードを HTML 5 として処理します。

encoding

オプションの引数。文字を変換するときに使うエンコーディングを定義します。

省略した場合の encoding のデフォルト値は、 default_charset の値を使います。

技術的にはこの引数を省略可能ですが、 default_charset の指定が入力とは違う文字セットになっている可能性もあるので、 適切な値を指定しておくことを強く推奨します。

以下の文字セットをサポートします。

サポートする文字セット
文字セット エイリアス 説明
ISO-8859-1 ISO8859-1 西欧、Latin-1
ISO-8859-5 ISO8859-5 ほとんど使われないキリル文字セット (Latin/Cyrillic)。
ISO-8859-15 ISO8859-15 西欧、Latin-9 。Latin-1(ISO-8859-1) に欠けている ユーロ記号やフランス・フィンランドの文字を追加したもの。
UTF-8   ASCII 互換のマルチバイト 8 ビット Unicode 。
cp866 ibm866, 866 DOS 固有のキリル文字セット。
cp1251 Windows-1251, win-1251, 1251 Windows 固有のキリル文字セット。
cp1252 Windows-1252, 1252 西欧のための Windows 固有の文字セット。
KOI8-R koi8-ru, koi8r ロシア語。
BIG5 950 繁体字中国語。主に台湾で使用されます。
GB2312 936 簡体字中国語。国の標準文字セットです。
BIG5-HKSCS   Big5 に香港の拡張を含めたもの。繁体字中国語。
Shift_JIS SJIS, SJIS-win, cp932, 932 日本語。
EUC-JP EUCJP, eucJP-win 日本語。
MacRoman   Mac OS で使われる文字セット。
''   空文字列を指定すると、 スクリプトのエンコーディング (Zend multibyte)、 default_charset、 そして現在のロケール (nl_langinfo() および setlocale() を参照ください) の順でエンコーディングを検出します。 この方法はおすすめしません。

注意: これら以外の文字セットは理解できません。 かわりにデフォルトのエンコーディングを使用し、警告を発生させます。

double_encode

double_encode をオフにすると、PHP は既存の html エンティティをエンコードしません。 デフォルトでは、既存のエンティティも含めてすべてを変換します。

戻り値

エンコードした文字列を返します。

入力文字列の中に、指定した encoding で無効な符号単位シーケンスが含まれる場合は、 ENT_IGNORE あるいは ENT_SUBSTITUTE フラグが設定されていない限りは空文字列を返します。

変更履歴

バージョン 説明
8.1.0 flags のデフォルト値が ENT_COMPAT から ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 に変更されました。
8.0.0 encoding は、nullable になりました。

例1 htmlentities() の例

<?php
$str
= "A 'quote' is <b>bold</b>";

// 出力: A 'quote' is &lt;b&gt;bold&lt;/b&gt;
echo htmlentities($str);

// 出力: A &#039;quote&#039; is &lt;b&gt;bold&lt;/b&gt;
echo htmlentities($str, ENT_QUOTES);
?>

例2 ENT_IGNORE の使用例

<?php
$str
= "\x8F!!!";

// 出力: 空の文字列
echo htmlentities($str, ENT_QUOTES, "UTF-8");

// 出力: "!!!"
echo htmlentities($str, ENT_QUOTES | ENT_IGNORE, "UTF-8");
?>

参考

add a note

User Contributed Notes 22 notes

up
159
Sijmen Ruwhof
14 years ago
An important note below about using this function to secure your application against Cross Site Scripting (XSS) vulnerabilities.

When printing user input in an attribute of an HTML tag, the default configuration of htmlEntities() doesn't protect you against XSS, when using single quotes to define the border of the tag's attribute-value. XSS is then possible by injecting a single quote:

<?php
$_GET
['a'] = "#000' onload='alert(document.cookie)";
?>

XSS possible (insecure):

<?php
$href
= htmlEntities($_GET['a']);
print
"<body bgcolor='$href'>"; # results in: <body bgcolor='#000' onload='alert(document.cookie)'>
?>

Use the 'ENT_QUOTES' quote style option, to ensure no XSS is possible and your application is secure:

<?php
$href
= htmlEntities($_GET['a'], ENT_QUOTES);
print
"<body bgcolor='$href'>"; # results in: <body bgcolor='#000&#039; onload=&#039;alert(document.cookie)'>
?>

The 'ENT_QUOTES' option doesn't protect you against javascript evaluation in certain tag's attributes, like the 'href' attribute of the 'a' tag. When clicked on the link below, the given JavaScript will get executed:

<?php
$_GET
['a'] = 'javascript:alert(document.cookie)';
$href = htmlEntities($_GET['a'], ENT_QUOTES);
print
"<a href='$href'>link</a>"; # results in: <a href='javascript:alert(document.cookie)'>link</a>
?>
up
5
j2teamnnl at gmail dot com
2 years ago
The answer above is not correct for multiple languages like France
I had correct it
function xml_entities($strIn)
{
if (is_numeric($strIn)) {
return $strIn;
}
$strOut = null;

$arrStr = mb_str_split($strIn);
foreach ($arrStr as $char) {
$ord = mb_ord($char);

if (($ord > 0 && $ord < 32) || ($ord >= 127)) {
$strOut .= "&amp;#{$ord};";
}
else {
switch ($char) {
case '<':
$strOut .= '&lt;';
break;
case '>':
$strOut .= '&gt;';
break;
case '&':
$strOut .= '&amp;';
break;
case '"':
$strOut .= '&quot;';
break;
default:
$strOut .= $char;
}
}
}

return $strOut;
}
up
25
q (dot) rendeiro (at) gmail (dot) com
17 years ago
I've seen lots of functions to convert all the entities, but I needed to do a fulltext search in a db field that had named entities instead of numeric entities (edited by tinymce), so I searched the tinymce source and found a string with the value->entity mapping. So, i wrote the following function to encode the user's query with named entities.

The string I used is different of the original, because i didn't want to convert ' or ". The string is too long, so I had to cut it. To get the original check TinyMCE source and search for nbsp or other entity ;)

<?php

$entities_unmatched
= explode(',', '160,nbsp,161,iexcl,162,cent, [...] ');
$even = 1;
foreach(
$entities_unmatched as $c) {
if(
$even) {
$ord = $c;
} else {
$entities_table[$ord] = $c;
}
$even = 1 - $even;
}

function
encode_named_entities($str) {
global
$entities_table;

$encoded_str = '';
for(
$i = 0; $i < strlen($str); $i++) {
$ent = @$entities_table[ord($str{$i})];
if(
$ent) {
$encoded_str .= "&$ent;";
} else {
$encoded_str .= $str{$i};
}
}
return
$encoded_str;
}

?>
up
4
2962051004 at qq dot com
6 years ago
<?php

/**
* 将中文转为Html实体
* Convert Chinese in HTML to entity
* Author QiangGe
* Mail 2962051004@qq.com
*
*/

$str = <<<EOT
你好 world
EOT;

function
ChineseToEntity($str) {
return
preg_replace_callback(
'/[\x{4e00}-\x{9fa5}]/u', // utf-8
// '/[\x7f-\xff]+/', // if gb2312
function ($matches) {
$json = json_encode(array($matches[0]));
preg_match('/\[\"(.*)\"\]/', $json, $arr);
/*
* 通过json_encode函数将中文转为unicode
* 然后用正则取出unicode
* Turn the Chinese into Unicode through the json_encode function, then extract Unicode from regular.
* I think this idea is seamless.
*/
return '&#x'. str_replace('\\u', '', $arr[1]). ';';
},
$str
);
}

echo
ChineseToEntity($str);
// &#x4f60;&#x597d; world
up
17
phil at lavin dot me dot uk
14 years ago
The following will make a string completely safe for XML:

<?php
function philsXMLClean($strin) {
$strout = null;

for (
$i = 0; $i < strlen($strin); $i++) {
$ord = ord($strin[$i]);

if ((
$ord > 0 && $ord < 32) || ($ord >= 127)) {
$strout .= "&amp;#{$ord};";
}
else {
switch (
$strin[$i]) {
case
'<':
$strout .= '&lt;';
break;
case
'>':
$strout .= '&gt;';
break;
case
'&':
$strout .= '&amp;';
break;
case
'"':
$strout .= '&quot;';
break;
default:
$strout .= $strin[$i];
}
}
}

return
$strout;
}
?>
up
12
hajo-p
10 years ago
The flag ENT_HTML5 also strips newline chars like \n with htmlentities while htmlspecialchars is not affected by that.

If you want to use nl2br on that string afterwards you might end up searching the problem like i did. This does not apply to other flags like e.g. ENT_XHTML which confused me.

Tested this with PHP 5.4 / 5.5 / 5.6-dev with same results, so it seems that this is an intended "feature".
up
12
realcj at g mail dt com
17 years ago
If you are building a loadvars page for Flash and have problems with special chars such as " & ", " ' " etc, you should escape them for flash:

Try trace(escape("&")); in flash' actionscript to see the escape code for &;

% = %25
& = %26
' = %27

<?php
function flashentities($string){
return
str_replace(array("&","'"),array("%26","%27"),$string);
}
?>

Those are the two that concerned me. YMMV.
up
13
ustimenko dot alexander at gmail dot com
12 years ago
For those Spanish (and not only) folks, that want their national letters back after htmlentities :)

<?php
protected function _decodeAccented($encodedValue, $options = array()) {
$options += array(
'quote' => ENT_NOQUOTES,
'encoding' => 'UTF-8',
);
return
preg_replace_callback(
'/&\w(acute|uml|tilde);/',
create_function(
'$m',
'return html_entity_decode($m[0], ' . $options['quote'] . ', "' .
$options['encoding'] . '");'
),
$encodedValue
);
}
?>
up
11
wd at NOSPAMwd dot it
12 years ago
Hi there,

after several and several tests, I figured out that dot:

- htmlentities() function remove characters like "à","è",etc when you specify a flag and a charset

- htmlentities() function DOES NOT remove characters like those above when you DO NOT specify anything

So, let's assume that..

<?php

$str
= "Hèèèllooo";

$res_1 = htmlentities($str, ENT_QUOTES, "UTF-8");
$res_2 = htmlentities($str);

echo
var_dump($res_1); // Result: string '' (length=0)
echo var_dump($res_2); // string 'H&egrave;&egrave;&egrave;llooo' (length=30)

?>

I used this for a textarea content for comments. Anyway, note that using the "$res_2" form the function will leave unconverted single/double quotes. At this point you should use str_replace() function to perform the characters but be careful because..

<?php

$str
= "'Hèèèllooo'";

$res_2 = str_replace("'","&#039;",$str);
$res_2 = htmlentities($str);
echo
var_dump($res_2); // string '&amp;#039;H&egrave;&egrave;&egrave;llooo&amp;#039;'

$res_3 = htmlentities($str);
$res_3 = str_replace("'","&#039;",$res_3);
echo
var_dump($res_3); // string '&#039;H&egrave;&egrave;&egrave;llooo&#039;' --> Nice
?>

Hope it will helps you.

Regards,
W.D.
up
13
n at erui dot eu
12 years ago
html entities does not encode all unicode characters. It encodes what it can [all of latin1], and the others slip through. &#1033; is the nasty I use. I have searched for a function which encodes everything, but in the end I wrote this. This is as simple as I can get it. Consult an ansii table to custom include/omit chars you want/don't. I'm sure it's not that fast.

// Unicode-proof htmlentities.
// Returns 'normal' chars as chars and weirdos as numeric html entites.
function superentities( $str ){
// get rid of existing entities else double-escape
$str = html_entity_decode(stripslashes($str),ENT_QUOTES,'UTF-8');
$ar = preg_split('/(?<!^)(?!$)/u', $str ); // return array of every multi-byte character
foreach ($ar as $c){
$o = ord($c);
if ( (strlen($c) > 1) || /* multi-byte [unicode] */
($o <32 || $o > 126) || /* <- control / latin weirdos -> */
($o >33 && $o < 40) ||/* quotes + ambersand */
($o >59 && $o < 63) /* html */
) {
// convert to numeric entity
$c = mb_encode_numericentity($c,array (0x0, 0xffff, 0, 0xffff), 'UTF-8');
}
$str2 .= $c;
}
return $str2;
}
up
5
Bassie (:
21 years ago
Note that you'll have use htmlentities() before any other function who'll edit text like nl2br().

If you use nl2br() first, the htmlentities() function will change < br > to &lt;br&gt;.