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

[1oo%, EoF]

Понравилась статья? Расскажите о ней друзьям:

Метки: PHP

Комментарии

Показать/скрыть правила
Имя
[i] [b] [u] [s] [url]
:-) ;-) :D *lol* 8-) :-* :-| :-( *cry* :o :-? *unsure* *oops* :-x *shocked* *zzz* :P *evil*

Осталось 1000 символов.
Код защиты от спама Обновить код
Каждый комментарий проходит ручную модерацию. 100% фильтрация спама.
Для работы модуля комментариев включите javaScript

Продвижение
Время
Метки