htmlspecialchars() и пустота. php 5.4.
Если вы заметили, что функция htmlspecialchars() начала возвращать пустую строку (внешний признак — пустые поля в формочках), не пугайтесь. Это не баг, это фича.
Именно так по замыслу разработчиков PHP и должна работать функция со строками в кодировке cp1251 и прочими «нацменьшинствами». Вы, кончено, будете возражать: «Раньше работала нормально. Значит — баг!» Ничего подобного! Задокументированный баг считается фичей. Вот вам выдержка из инструкции по миграции с php 5.3 на php 5.4:
Кодировкой по умолчанию для функций htmlspecialchars() и htmlentities() сейчас является UTF-8, вместо прежней ISO-8859-1. Обратите внимание, что изменения кодировки вывода с помощью конфигурационной опции default_charset не действует на вышеупомянутые функции до тех пор, пока вы не передадите «» (пустую строку) в качестве параметра кодировки в вызовы функций htmlspecialchars()/ htmlentities(). В целом, мы не рекомендуем так делать, потому что вы должны иметь возможность изменить кодировку вывода без воздействия на кодировку во время исполнения, используемую этими функциями. Самый безопасный подход — явно установить кодировку при каждом вызове функций htmlspecialchars() и htmlentities().
То есть, разработчикам и эксплуататорам движков и скриптов, использующих кодировку отличную от utf-8 предлагается либо переходить на utf-8, либо исправлять все(!) вхождения функций htmlspecialchars() и htmlentities() на такой, полный, формат:
htmlspecialchars($str, ФЛАГ, 'кодировка сайта');
Однако, можно попробовать использовать более универсальный код (в 5.6 уже не работает):
htmlspecialchars($str, NULL, '');
Такой код избавит вас от необходимости каждый раз править все вызовы при смене кодировки, что очень важно, если заранее не известно, в какой кодировке придется работать скрипту. Этот «универсальный» код работает и с utf-8, и с cp1251 в php 5.4.6 даже без маневров с default_charset. То есть — как раньше. Видимо из-за этого, разработчики его и не рекомендуют 😉
А что делать тем, у кого скрипты свёрнуты ионкубом или зендом? Выпить йаду. Договаривать с хостером об откате php на предыдущую версию, менять хостера, брать VPS/VDS, короче, крутиться кто как может, не забывая посылать лучи ненависти в строну разрабов php.
В заключение хочу искренне поблагодарить разработчиков php, что они не вспомнили о функциях preg_*, которые тоже можно было перевести на utf по умолчанию, изменив смысл флага «u» на противоположный.
UPD В PHP 5.6 код: htmlspecialchars($str, NULL, '');
тоже возвращает пустую строку.
Спасибо, Андрей, за уточнение.
Отличное решение, спасибо. Название статьи тоже оценил :-))
спасибо большое
Спасибо за информацию!
P.S.
В PHP 5.6 код:
htmlspecialchars($str, NULL, '');
тоже возвращает пустую строку.
Как в сказке: чем дальше, тем страшнее 🙂
Вы просто Спаситель!!!!
Спасибо за разъяснения. Всегда работал с utf-8, но на днях взялся за рефакторинг проекта с ср1251… И мозги плавились, пока не нашёл эту статью.
Горек удел программиста, блин…
Спасибо за информацию!
Сайт на cp1251, движок самописный, и пришлось несколько часов ломать голову, куда подевались элементы сайта, обработанные htmlspecialchars(). В общем-то причину я нашел сразу, но ваше сообщение подтвердило, что я не ошибся.
остается единственный косяк с которым я не могу совладать: с RSS-лентой что делать? отображается нормально, но в исходном коде страницы квадратики и экспортируются на другие сервисы каракули.
Большое спасибо. Именно эта мысль и спасла один проект!!
Автору спасибо.
Спасибо за подсказку, тоже столкнулся с этой проблемой.
Спасибо! … помогло
Спасибо, полностью описали ситуацию, случившуюся в «один прекрасный день» и пути решения
Огромное спасибо, Юрий.
Среди всех сайтов, которые тупо копируют официальную документацию и не предоставляют реального примера, ваш блог оказался «конкретным решением» задачи. У меня ушло около 2х часов,что бы понять в чем причина и на разные решения, типа смены кодировки на лету. Но ваша пример в виде ОДНОЙ СТРОЧКИ КОДА решил проблему на корню. Большое спасибо! С уважением
На мой взгляд, подход правильный — давно уже нужно было перевести PHP на нечто более универсальное. В моих проектах все решалось использованием UTF-8 с самого начала. В результате, ничего менять не понадобилось в коде.
В одном месте вспомнить про utf (похерив при этом default charset) и забыть в десятках других мест — это не подход. Это «так получилось».