Как декодировать числовые сущности HTML в PHP - PullRequest
13 голосов
/ 04 мая 2010

Я пытаюсь декодировать закодированную длинную черту из числового объекта в строку, но мне кажется, что я не могу найти функцию, которая может сделать это правильно.

Лучшее, что я нашел, это mb_decode_numericentity (), однако по какой-то причине он не может декодировать длинную черту и некоторые другие специальные символы.

$str = '–';

$str = mb_decode_numericentity($str, array(0xFF, 0x2FFFF, 0, 0xFFFF), 'ISO-8859-1');

Это вернет "?".

Кто-нибудь знает, как решить эту проблему?

Ответы [ 2 ]

19 голосов
/ 05 июня 2011

Следующий фрагмент кода (в основном украденный из здесь и улучшенный) будет работать для буквенных, числовых десятичных и числовых шестнадцатеричных объектов:

header("content-type: text/html; charset=utf-8");

/**
* Decodes all HTML entities, including numeric and hexadecimal ones.
* 
* @param mixed $string
* @return string decoded HTML
*/

function html_entity_decode_numeric($string, $quote_style = ENT_COMPAT, $charset = "utf-8")
{
$string = html_entity_decode($string, $quote_style, $charset);
$string = preg_replace_callback('~&#x([0-9a-fA-F]+);~i', "chr_utf8_callback", $string);
$string = preg_replace('~&#([0-9]+);~e', 'chr_utf8("\\1")', $string);
return $string; 
}

/** 
 * Callback helper 
 */

function chr_utf8_callback($matches)
 { 
  return chr_utf8(hexdec($matches[1])); 
 }

/**
* Multi-byte chr(): Will turn a numeric argument into a UTF-8 string.
* 
* @param mixed $num
* @return string
*/

function chr_utf8($num)
{
if ($num < 128) return chr($num);
if ($num < 2048) return chr(($num >> 6) + 192) . chr(($num & 63) + 128);
if ($num < 65536) return chr(($num >> 12) + 224) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
if ($num < 2097152) return chr(($num >> 18) + 240) . chr((($num >> 12) & 63) + 128) . chr((($num >> 6) & 63) + 128) . chr(($num & 63) + 128);
return '';
}


$string ="&#x201D;"; 

echo html_entity_decode_numeric($string);

Предложения по улучшению приветствуются.

1 голос
/ 04 мая 2010

mb_decode_numericentity не обрабатывает шестнадцатеричное, только десятичное. Получаете ли вы ожидаемый результат с:

$str = '–';

$str = mb_decode_numericentity ( $str , Array(255, 3145727, 0, 65535) , 'ISO-8859-1');

Вы можете использовать hexdec для преобразования вашего шестнадцатеричного в десятичное.

Также из любопытства выполняет следующую работу:

$str = '&#8211;';

 $str = html_entity_decode($str);
...