PHP: засада с strlen()
версия для печатиВот и я наступил на эти грабли.. :( Во-первых, я невнимательно читал мануал. Разница между strlen() и ее мультибайтным аналогом, mb_strlen(), в том, что первая считает байты в строке, а вторая - символы. В однобайтных кодировках разницы нет, но для мультибайтных (например utf-8), значения функций будут разные, если в строке есть буквы национального алфавита. Это меня не парило, пока не столкнулся с багом. На локалке код работает, на сервере падает с кракозяброй в сообщении об ошибке.
Практический пример. Скрипт работает с Redis через сокеты, все в utf-8. Нужно узнать количество байт в строке. И функция strlen() с этим справляется.. пока не перегружается функцией mb_strlen(). Эта, в свою очередь, считает количество символов, а не байт, и получаем классный баг! Почему же работает на локалке? А у меня не включена настройка "mbstring.func_overload" в php.ini, поэтому нет перегрузки функций и strlen() никем на лету не подменяется.
Варианты решения:
//всегда будет считать по байтам, без разницы, что настроено
$bytes = mb_strlen($strVar, '8bit');
//Или более заковыристо:
$bytes = function_exists('mb_strlen') ? mb_strlen($block, '8bit') : strlen($block);
//в этом случае перегрузка функции просто невозможна, нет ее заместителя
О перегрузке функций написано тут: http://php.net/manual/ru/mbstring.overload.php
О косяке и выходе из него тут: http://php.net/manual/ru/function.mb-strlen.php#77040
Понравилась статья? Расскажите о ней друзьям: