【问题标题】:htmlentites not working for emojihtmlentities 不适用于表情符号
【发布时间】:2016-04-29 14:40:39
【问题描述】:

我正在尝试显示一个字符 html 实体

echo htmlentities(htmlentities("&"));
//outputs &
echo htmlentities(htmlentities("<"));
//outputs &lt;

但它似乎不适用于表情符号

echo htmlentities(htmlentities("????"));
//outputs ????

如何让它输出&amp;#128526;


编辑:

我正在尝试显示用户输入的字符串,其中包含所有已编码的 html 实体。
echo htmlentities(htmlentities($input))

示例: "this &amp; that ????" -&gt; "this &amp;amp; that &amp;#128526;"

【问题讨论】:

  • 出于好奇.. 为什么要这样做?如果您要输出 unicode,则不需要实体。
  • echo htmlentities(htmlentities("&amp;")); 输出&amp;amp;amp;
  • 如果内容类型是 text/html,则不会。第一个&转换为 &
  • @TonyBrix 否,您的浏览器显示为&amp;amp;,但未转换,请检查页面来源
  • @Evert 我正在尝试向用户显示 html 实体代码

标签: php html-entities emoji


【解决方案1】:

$emoji = "\xF0\x9F\x98\x8E"; // 这是你的表情符号

我从convert unicode to html entities hex得到这个回调

$hex = preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($m) {
    $char = current($m);
    $utf = iconv('UTF-8', 'UCS-4', $char);
    return sprintf("&#x%s;", ltrim(strtoupper(bin2hex($utf)), "0"));
}, $emoji);

echo $hex;

echo json_encode(("\xF0\x9F\x98\x8E")); // 已解码。 htmlentities 不适用于它。

这样好吗?

【讨论】:

  • 这不适用于常规的 html 实体。我要转换的字符串是用户输入的,所以我不知道它是“?”还是“&”还是“A”。我需要一个函数,它接受任何输入并输出一个带有 html 实体编码的字符串
  • 输入也可以是多个字符的字符串
  • 如何使用类似的东西而不是 htmlentities ? php.net/manual/en/function.bin2hex.php#48861 你可能需要做一个基准测试。不过看起来还可以。
  • 顺便说一句,无法使用 html_special_chars 或 htmlentities 清理这些输入,请查看此内容。 github.com/php/php-src/blob/PHP-5.6.18/ext/standard/tests/… 它是用于 htmlentities 和特殊字符的表格
【解决方案2】:

这当然适用于常规 HTML 实体、UTF-8 表情符号(和其他 utf 内容)以及常规字符串。

我只是遇到了空字符串值的问题,所以我不得不将这个条件放入函数中。

function entities( $string ) {
    $stringBuilder = "";
    $offset = 0;

    if ( empty( $string ) ) {
        return "";
    }

    while ( $offset >= 0 ) {
        $decValue = ordutf8( $string, $offset );
        $char = unichr($decValue);

        $htmlEntited = htmlentities( $char );
        if( $char != $htmlEntited ){
            $stringBuilder .= $htmlEntited;
        } elseif( $decValue >= 128 ){
            $stringBuilder .= "&#" . $decValue . ";";
        } else {
            $stringBuilder .= $char;
        }
    }

    return $stringBuilder;
}

// source - http://php.net/manual/en/function.ord.php#109812
function ordutf8($string, &$offset) {
    $code = ord(substr($string, $offset,1));
    if ($code >= 128) {        //otherwise 0xxxxxxx
        if ($code < 224) $bytesnumber = 2;                //110xxxxx
        else if ($code < 240) $bytesnumber = 3;        //1110xxxx
        else if ($code < 248) $bytesnumber = 4;    //11110xxx
        $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0);
        for ($i = 2; $i <= $bytesnumber; $i++) {
            $offset ++;
            $code2 = ord(substr($string, $offset, 1)) - 128;        //10xxxxxx
            $codetemp = $codetemp*64 + $code2;
        }
        $code = $codetemp;
    }
    $offset += 1;
    if ($offset >= strlen($string)) $offset = -1;
    return $code;
}

// source - http://php.net/manual/en/function.chr.php#88611
function unichr($u) {
    return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
}

/* ---- */

var_dump( entities( "&" ) ) . "\n";
var_dump( entities( "<" ) ) . "\n";
var_dump( entities( "?" ) ) . "\n";
var_dump( entities( "☚" ) ) . "\n";
var_dump( entities( "" ) ) . "\n";
var_dump( entities( "A" ) ) . "\n";
var_dump( entities( "Hello ? world" ) ) . "\n";
var_dump( entities( "this & that ?" ) ) . "\n";

【讨论】:

    【解决方案3】:

    htmlentities 文档指出

    所有具有 HTML 字符实体等价物的字符都是 翻译成这些实体。

    您的 emoji 没有类似 &amp;lt; 的对应 &lt;,因此它不会被转换。 &amp;#128526; 只是一个 HTML 代码,而不是 HTML 实体。

    function htmlEntitiesOrCode($string) {
        //try htmlentities first
        $result = htmlentities($string, ENT_COMPAT, "UTF-8");
    
        //if the output is different from input, an entity was returned
        if ($result != $string) {
            return $result;
        }
    
        //get the html code
        $offset = 0;
        $code = ord(substr($string, $offset,1));
        if ($code >= 128) {
            if ($code < 224) {
                $bytesnumber = 2;
            } else if ($code < 240) {
                $bytesnumber = 3;
            } else if ($code < 248) {
                $bytesnumber = 4;
            }
            $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0);
            for ($i = 2; $i <= $bytesnumber; $i++) {
                $offset ++;
                $code2 = ord(substr($string, $offset, 1)) - 128;
                $codetemp = $codetemp*64 + $code2;
            }
            $code = $codetemp;
        }
        $offset += 1;
        if ($offset >= strlen($string)) {
            $offset = -1;
        }
    
        $result = "&#" . $code;
        return $result;
    }
    

    HTML 代码函数取自这里:http://php.net/manual/en/function.ord.php#109812

    【讨论】:

      猜你喜欢
      • 2017-06-30
      • 2017-06-24
      • 2021-06-03
      • 2016-10-11
      • 1970-01-01
      • 2018-06-22
      • 2023-01-05
      • 1970-01-01
      • 2022-07-14
      相关资源
      最近更新 更多