Intereting Posts
как передавать HTTP-аутентификацию с помощью jquery для аутентификации системы входа? Php CLI скрипт игнорирует memory_limit, сбой при гораздо меньшем числе, чем предел openssl_verify и "error: 0906D06C: PEM-процедуры: PEM_read_bio: нет стартовой строки" Настройка ChromePhp для WordPress с помощью Xampp Как получить часовой пояс от кода аэропорта (IATA / FAA) Пустая страница на кнопке отправки Автоматическая таблица обновления без обновления страницы PHP MySQL Реализация GCM с использованием PHP, всегда сталкивающегося с неавторизованной ошибкой 401 Сделать URL-адрес, чувствительный к SEO, (исключить идентификатор). Уметь менять цвет отдельных разделов, нажимая на кнопки Сортируемый список Jquery не будет сериализоваться, почему? Laravel принадлежит Не работает PHP: отображать содержимое после принудительной загрузки? как получить доступ к argv и параметрам вместе в php через аргументы командной строки Как математически оценить строку типа «2-1» для создания «1»?

html_entity_decode – проблема с кодировкой символов

У меня проблемы с кодировкой символов. Я упростил этот сценарий ниже:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <?php $string = 'Stan’s'; echo $string.'<br><br>'; // Stan's echo html_entity_decode($string).'<br><br>'; // Stan's echo html_entity_decode($string, ENT_QUOTES, 'UTF-8'); // Stans ?> </body> </html> 

Я хотел бы использовать последнее echo . Однако он удаляет ' почему?

Обновить

Я пробовал все три варианта ENT_COMPAT , ENT_QUOTES , ENT_NOQUOTES и он удаляет ' во всех случаях».

Проблема в том, что &#146; декодирует символ Unicode U + 0092, UTF-8 C2 92 , известный как ЧАСТНОЕ ИСПОЛЬЗОВАНИЕ ДВА:

 $ php test.php | xxd 0000000: 5374 616e c292 73 Stan..s 

То есть, это не расшифровывается до обычного апострофа.

html_entity_decode($string) работает, потому что он фактически не декодирует объект, так как целевая кодировка по умолчанию – latin-1, которая не может представлять этот символ. Если вы укажете UTF-8 в качестве целевой кодировки, объект фактически декодируется.

Целью этого объекта является кодировка Windows-1252:

 echo iconv('cp1252', 'UTF-8', html_entity_decode('Stan&#146;s', ENT_QUOTES, 'cp1252')); Stan's 

Цитата Википедии :

Числовые ссылки всегда относятся к кодам Unicode, независимо от кодировки страницы. Запрещается использование числовых ссылок, которые ссылаются на постоянно неопределенные символы и управляющие символы, за исключением символов перевода строки, табуляции и возврата каретки. То есть символы в шестнадцатеричных диапазонах 00-08, 0B-0C, 0E-1F, 7F и 80-9F не могут использоваться в HTML-документе, даже не по ссылке, поэтому &#153; , например, не допускается. Однако для обратной совместимости с ранними авторами HTML и браузерами, которые игнорировали это ограничение, необработанные символы и числовые ссылки на символы в диапазоне 80-9F интерпретируются некоторыми браузерами как представляющие символы, сопоставленные байтам 80-9F в кодировке Windows-1252.

Таким образом, вы имеете дело с устаревшими объектами HTML здесь, что, по-видимому, PHP не работает так же, как это делают «некоторые» браузеры. Вы можете проверить, находятся ли декодированные объекты в указанном выше диапазоне, что вы перекодируете / сокращаете их в Windows-1252, а затем конвертируете в UTF-8. Или попросите своих пользователей передать действительный HTML.

Эта функция должна обрабатывать как устаревшие, так и обычные объекты HTML:

 function legacy_html_entity_decode($str, $quotes = ENT_QUOTES, $charset = 'UTF-8') { return preg_replace_callback('/&#(\d+);/', function ($m) use ($quotes, $charset) { if (0x80 <= $m[1] && $m[1] <= 0x9F) { return iconv('cp1252', $charset, html_entity_decode($m[0], $quotes, 'cp1252')); } return html_entity_decode($m[0], $quotes, $charset); }, $str); }