htmlentites не работает для смайликов

Я пытаюсь показать персонажи HTML-сущности

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

но это не похоже на работу с Emoji

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

Как я могу получить его на выходе &#128526;?


Редактировать:

Я пытаюсь отобразить строку ввода пользователя со всеми закодированными HTML-сущностями.
echo htmlentities(htmlentities($input))

Пример:
"this & that ��" -> "this &amp; that &#128526;"

6

Решение

Это работает для обычных сущностей 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";
6

Другие решения

$emoji = "\xF0\x9F\x98\x8E"; // это ваши смайлики

Я получаю этот звонок от конвертировать юникод в html сущности 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 не работает с этим.

Это нормально ?

2

htmlentities документация утверждает, что

все символы, которые имеют эквиваленты объекта HTML
переведены на эти лица.

Ваш эмодзи не имеет эквивалента &lt; для <так что это не конвертируется. &#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

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector