• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • htmlentities()

    (PHP 4, PHP 5, PHP 7)

    将字符转换为 HTML 转义字符

    说明

    htmlentities(string $string[,int $flags= ENT_COMPAT | ENT_HTML401[,string $encoding= ini_get("default_charset")[,bool $double_encode= true]]]) : string

    本函数各方面都和htmlspecialchars()一样,除了htmlentities()会转换所有具有 HTML 实体的字符。

    如果要解码(反向操作),可以使用html_entity_decode()。

    参数

    $string

    输入字符。

    $flags

    以下一组位掩码标记,用于设置如何处理引号、无效代码序列、使用文档的类型。默认是ENT_COMPAT | ENT_HTML401

    有效$flags标记常量
    常量名描述
    ENT_COMPAT会转换双引号,不转换单引号。
    ENT_QUOTES既转换双引号也转换单引号。
    ENT_NOQUOTES单/双引号都不转换
    ENT_IGNORE静默丢弃无效的代码单元序列,而不是返回空字符串。不建议使用此标记,因为它»可能有安全影响。
    ENT_SUBSTITUTE替换无效的代码单元序列为 Unicode 代替符(Replacement Character), U+FFFD (UTF-8)或者�(其他),而不是返回空字符串。
    ENT_DISALLOWED为文档的无效代码点替换为 Unicode 代替符(Replacement Character): U+FFFD (UTF-8),或�(其他),而不是把它们留在原处。比如以下情况下就很有用:要保证 XML 文档嵌入额外内容时格式合法。
    ENT_HTML401以 HTML 4.01 处理代码。
    ENT_XML1以 XML 1 处理代码。
    ENT_XHTML以 XHTML 处理代码。
    ENT_HTML5以 HTML 5 处理代码。
    $encoding

    An optional argument defining the encoding used when converting characters.

    If omitted, the default value of the$encodingvaries depending on the PHP version in use. In PHP 5.6 and later,thedefault_charsetconfiguration option is used as the default value. PHP 5.4 and 5.5 will useUTF-8as the default. Earlier versions of PHP useISO-8859-1.

    Although this argument is technically optional, you are highly encouraged to specify the correct value for your code if you are using PHP 5.5 or earlier, or if yourdefault_charsetconfiguration option may be set incorrectly for the given input.

    支持以下字符集:

    支持的字符集列表
    字符集别名描述
    ISO-8859-1ISO8859-1西欧,Latin-1
    ISO-8859-5ISO8859-5Little used cyrillic charset (Latin/Cyrillic).
    ISO-8859-15ISO8859-15西欧,Latin-9。增加欧元符号,法语和芬兰语字母在 Latin-1(ISO-8859-1)中缺失。
    UTF-8ASCII 兼容的多字节 8 位 Unicode。
    cp866ibm866, 866DOS 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
    cp1251Windows-1251, win-1251, 1251Windows 特有的西里尔编码。本字符集在 4.3.2 版本中得到支持。
    cp1252Windows-1252, 1252Windows 特有的西欧编码。
    KOI8-Rkoi8-ru, koi8r俄语。本字符集在 4.3.2 版本中得到支持。
    BIG5950繁体中文,主要用于中国台湾省。
    GB2312936简体中文,中国国家标准字符集。
    BIG5-HKSCS繁体中文,附带香港扩展的 Big5 字符集。
    Shift_JISSJIS, 932日语
    EUC-JPEUCJP日语
    MacRomanMac OS 使用的字符串。
    ''An empty string activates detection from script encoding (Zend multibyte),default_charsetand current locale (seenl_langinfo()andsetlocale()), in this order. Not recommended.

    Note:其他字符集没有认可。将会使用默认编码并抛出异常。

    $double_encode

    关闭$double_encode时,PHP 不会转换现有的 HTML 实体,默认是全部转换。

    返回值

    返回编码后的字符。

    如果指定的编码$encoding里,$string包含了无效的代码单元序列,没有设置ENT_IGNORE或者ENT_SUBSTITUTE标记的情况下,会返回空字符串。

    更新日志

    版本说明
    5.6.0The default value for the$encodingparameter was changed to be the value of thedefault_charsetconfiguration option.
    5.4.0$encoding参数的默认值改成 UTF-8。
    5.4.0增加常量ENT_SUBSTITUTEENT_DISALLOWEDENT_HTML401ENT_XML1ENT_XHTMLENT_HTML5
    5.3.0增加常量ENT_IGNORE
    5.2.3增加参数$double_encode。

    范例

    Example #1htmlentities()例子

    <?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);
    ?>

    Example #2ENT_IGNORE用法示例

    <?php
    $str = "\x8F!!!";
    // 输出空 string
    echo htmlentities($str, ENT_QUOTES, "UTF-8");
    // 输出 "!!!"
    echo htmlentities($str, ENT_QUOTES  |  ENT_IGNORE, "UTF-8");
    ?>

    参见

    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>
    ?>
    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;
    }
    ?>
    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;
    }
    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;
    }
    ?>
    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.
    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".
    When putting values inside comment tags <!-- --> you should replace -- with &#45;&#45; too, as this would end your tag and show the rest of the comment.
    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.
    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
      );
    }
    ?>
    htmlentities seems to have changed at some point between version 5.1.6 and 5.3.3, such that it now returns an empty string for anything containing a pound sign:
    $ php -v
    PHP 5.1.6 (cli) (built: May 22 2008 09:08:44)
    $ php -r "echo htmlentities('£hello', null, 'utf-8');"
    &pound;hello
    $
    $ php -v
    PHP 5.3.3 (cli) (built: Aug 19 2010 12:07:49)
    $ php -r "echo htmlentities('£hello', null, 'utf-8');"
    $
    (Returns an empty string the second time)
    Just a heads up.
    I use this function to encode all the xml entities and also all the &something; that are not defined in xml like &trade;
    You can also decode what you encode with my decode function.
    My function works a little like the htmlentities.
    You can also add other string to the array if you want to exclude them from the encoding.
    <?php
    function xml_entity_decode($text, $charset = 'Windows-1252'){
      // Double decode, so if the value was &amp;trade; it will become Trademark
      $text = html_entity_decode($text, ENT_COMPAT, $charset);
      $text = html_entity_decode($text, ENT_COMPAT, $charset);
      return $text;
    }
    function xml_entities($text, $charset = 'Windows-1252'){
       // Debug and Test
      // $text = "test &amp; &trade; &amp;trade; abc &reg; &amp;reg; &#45;";
      
      // First we encode html characters that are also invalid in xml
      $text = htmlentities($text, ENT_COMPAT, $charset, false);
      
      // XML character entity array from Wiki
      // Note: &apos; is useless in UTF-8 or in UTF-16
      $arr_xml_special_char = array("&quot;","&amp;","&apos;","&lt;","&gt;");
      
      // Building the regex string to exclude all strings with xml special char
      $arr_xml_special_char_regex = "(?";
      foreach($arr_xml_special_char as $key => $value){
        $arr_xml_special_char_regex .= "(?!$value)";
      }
      $arr_xml_special_char_regex .= ")";
      
      // Scan the array for &something_not_xml; syntax
      $pattern = "/$arr_xml_special_char_regex&([a-zA-Z0-9]+;)/";
      
      // Replace the &something_not_xml; with &amp;something_not_xml;
      $replacement = '&amp;${1}';
      return preg_replace($pattern, $replacement, $text);
    }
    ?>
    There is a feature when writing to XML using an AJAX call to PHP that rarely is mentioned. I struggled for many hours using htmlentities() because what was getting written to my XML document was not as expected. I naturally assumed that I should be converting my strings before writing them to XML to adhere to XML rules on illegal characters. To my surprise, when converting with htmlentities() or htmlspecialchars() and then writing to an XML file, the resulting ampersands get converted afterwards! Consider the following example:
    <?php
    $str = "<b>I am cool</b>" ;
    $str = htmlentities($str) ;
    ?>
    When you append $str to an XML element and save() the document, you would expect the XML document's source code to look something like this:
    <ele>&lt;b&gt;I am cool&lt;/b&gt;</ele>
    But that is not what happens. The resulting ampersands get converted by PHP automatically to &amp; and your source code ends up looking like this:
    <ele>&amp;lt;b&amp;gt;I am cool&amp;lt;/b&amp;gt;</ele>
    As you can see, this creates problems when trying to output the XML data back to HTML. It is important to remember that when writing to XML this way, special characters like ">" and "<"; PHP converts them automatically and there becomes no need to use htmlentities() in certain cases. I assume this feature is in place to aid with passing data through header queries, to avoid reserved characters conflicting with others in a header query (e.g. & or =). Now I understand this may not be the case with older versions of PHP and that this might be a feature of my version (PHP version 5.6.32). With older versions, I assume using htmlentities() or htmlspecialchars() is a must, as stated with previous notes here. Also I use the charset UTF-8 in my HTML and XML and am not sure if this also effects the results I get.
    Anyway, I struggled for many hours with using htmlentities() to convert strings for XML writing and saving, when all I had to do was simply not use the function and let PHP convert my strings for me. I hope this helps because I would think I am not the only one who has struggled with this situation.
    A useful little function to convert the symbols in the different inputs.
    <?php
    function ConvertSimbols($var, $ConvertQuotes = 0) {
    if ($ConvertQuotes > 0) {
    $var = htmlentities($var, ENT_NOQUOTES, 'UTF-8');
    $var = str_replace('\"', '', $var);
    $var = str_replace("\'", '', $var);
    } else {
    $var = htmlentities($var, ENT_QUOTES, 'UTF-8');
    }
    return $var;
    }
    ?>
    Usage with quotes for example message:
    $message = ConvertSimbols($message);
    Usage without quotes for example link:
    $link = ConvertSimbols($link, 1);
    Note that as of 5.2.5 it appears that if the input string contains a character that is not valid for the output encoding you've specified, then this function returns null.
    You might expect it to just strip the invalid char, but it doesn't.
    You can strip the chars yourself like so:
    iconv('utf-8','utf-8',$str);
    You can combine that with htmlentities also:
    $str = htmlentities(iconv('UTF-8', 'UTF-8//IGNORE', $str, ENT_QUOTES, 'UTF-8');
    Should give you a string with htmlentities encoded to utf-8, and any unsupported chars stripped.
    This fuction is particularly useful against XSS (cross-site-scripting-). XSS makes use of holes in code, whether it be in Javascript or PHP. XSS often, if not always, uses HTML entities to do its evil deeds, so this function in co-operation with your scripts (particularly search or submitting scripts) is a very useful tool in combatting "H4X0rz".
    I'm glad 5.4 has xml support, but many of us are working with older installations, some of us still have to use PHP4. If you're like me you've been frustrated with trying to use htmlentites/htmlspecial chars with xml output. I was hoping to find an option to force numeric encoding, lacking that, I have written my own xmlencode function, which I now offer:
    usage: 
    $string xmlencode( $string )
    it will use htmlspecialchars for the valid xml entities amp, quote, lt, gt, (apos) and return the numeric entity for all other non alpha-numeric characters.
    -------------------------------------------
    <?php 
    if( !function_exists( 'xmlentities' ) ) {
      function xmlentities( $string ) {
        $not_in_list = "A-Z0-9a-z\s_-";
        return preg_replace_callback( "/[^{$not_in_list}]/" , 'get_xml_entity_at_index_0' , $string );
      }
      function get_xml_entity_at_index_0( $CHAR ) {
        if( !is_string( $CHAR[0] )  ||  ( strlen( $CHAR[0] ) > 1 ) ) {
          die( "function: 'get_xml_entity_at_index_0' requires data type: 'char' (single character). '{$CHAR[0]}' does not match this type." );
        }
        switch( $CHAR[0] ) {
          case "'":  case '"':  case '&':  case '<':  case '>':
            return htmlspecialchars( $CHAR[0], ENT_QUOTES );  break;
          default:
            return numeric_entity_4_char($CHAR[0]);        break;
        }    
      }
      function numeric_entity_4_char( $char ) {
        return "&#".str_pad(ord($char), 3, '0', STR_PAD_LEFT).";";
      }  
    }
    ?>
    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;.
    Trouble when using files with different charset?
    htmlentities and html_entity_decode can be used to translate between charset! 
    Sample function:
    <?php
    function utf2latin($text) {
      $text=htmlentities($text,ENT_COMPAT,'UTF-8');
      return html_entity_decode($text,ENT_COMPAT,'ISO-8859-1');
    }
    ?>
    <?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
    This function throws a warning on bad input even if ENT_SUBSTITUTE is set, so be prepared for this.
    A pointer to http://www.php.net/manual/en/function.mb-convert-encoding.php if your intention is to translate *all* characters in a charset to their corresponding HTML entities, not just named characters. Non-named characters will be replaced with HTML numeric encoding. eg:
    $text = mb_convert_encoding($text, 'HTML-ENTITIES', "UTF-8");