PHP многобайтовые строковые функции - PullRequest
4 голосов
/ 19 марта 2009

Сегодня я столкнулся с проблемой с функцией php strpos(), потому что она возвращала FALSE, даже если правильный результат был, очевидно, 0. Это было потому, что один параметр был закодирован в UTF-8, а другой (origin - HTTP GET параметр) явно нет.

Теперь я заметил, что использование функции mb_strpos решило мою проблему.

Теперь у меня вопрос: разумно ли использовать многобайтовые строковые функции PHP в целом, чтобы избежать этих проблем в будущем? Стоит ли вообще избегать традиционных функций strpos, strlen, ereg и т. Д. И т. П.?

Примечание: я не хочу устанавливать mbstring.func_overload global в php.ini, потому что это приводит к другим проблемам при использовании библиотеки PEAR. Я использую PHP4.

Ответы [ 5 ]

4 голосов
/ 19 марта 2009

Это зависит от используемой вами кодировки символов. В однобайтовых кодировках символов или UTF-8 (где один байт внутри символа никогда не может быть ошибочно принят за другой символ), тогда, пока строка, в которой вы ищете, и строка, которую вы используете для поиска, находятся в одном и том же кодирование, то вы можете продолжать использовать обычные функции поиска строки.

Если вы используете многобайтовую кодировку, отличную от UTF-8, которая не препятствует тому, чтобы отдельные байты в символе отображались как другие символы, то всегда невозможно выполнить поиск строки, используя обычные функции поиска строки. Вы можете найти ложные срабатывания. Это связано с тем, что сравнение строк в PHP в таких функциях, как strpos, выполняется по байтам, и, за исключением UTF-8, специально разработанного для предотвращения этой проблемы, многобайтовые кодировки страдают от проблемы, которая возникает из любого последующего байта символа более одного байта может совпадать с частью другого символа.

Если искомая строка в и искомая строка имеют разные кодировки символов, преобразование всегда будет необходимо. В противном случае вы обнаружите, что для любой строки, которая будет представлена ​​по-другому в другой кодировке, она всегда будет возвращать false. Вы должны выполнить такое преобразование при вводе: определитесь с кодировкой символов, которую будет использовать ваше приложение, и будьте последовательны в приложении. Каждый раз, когда вы получаете ввод в другой кодировке, конвертируйте по пути.

4 голосов
/ 19 марта 2009

Были некоторые проблемы с функциями mb_ * в версиях PHP до 5.2. Так что, если ваш код работает на нескольких платформах с разными версиями PHP, может произойти странное поведение. Кроме того, функция mb_ strpos довольно медленная, она должна пропускать количество символов, указанное параметром смещения, чтобы получить реальную позицию байта, используемую внутри. В циклах, в зависимости от функциональности strpos / mb_strpos, это может стать основным узким местом.

2 голосов
/ 19 марта 2009

Если вы используете одинаковую кодировку везде, это обычно не проблема. Я использую UTF-8 для всех своих страниц и никогда не сталкивался с этой проблемой. В конце концов, все сводится к указанию одинаковой кодировки для страниц и базы данных.

Например:

header('Content-type: text/html;charset=utf-8');
mysql_query('SET NAMES utf8');

В большинстве случаев это означает, что все источники данных для приложения будут доставлять данные в одной и той же кодировке, и, таким образом, вы избежите подобных проблем.

Все это будет намного лучше с появлением PHP 6, кстати, поскольку он будет включать полную поддержку Unicode.

1 голос
/ 19 марта 2009

Вам не обязательно использовать mb_strpos, но вам нужно убедиться, что все данные в вашем приложении одинаковы: либо mb_string, либо простая строка в одной конкретной кодировке. (Обычно UTF-8.)

Если вы убедитесь, что ваши страницы соответствуют UTF-8, а отправленные вами формы интерпретируются как UTF-8, а ваша база данных хранит UTF-8, вы, как правило, будете в порядке. Операции с индексированными строками (в частности усечения) могут нарушить последовательность UTF-8, что раздражает, но, как правило, не губительно. Если вам нужен такой уровень поддержки, mb_strings - это единственный вариант (но, конечно, вы должны убедиться, что все части вашего приложения, а также библиотеки и версия PHP справятся с ними должным образом).

Разработка сайтов, которые правильно обрабатывают Unicode в PHP, сейчас не слишком увлекательна: ее поддержка Unicode очень слабая по сравнению с такими языками, как Python и .NET. Есть надежда, что PHP6 улучшит ситуацию.

0 голосов
/ 20 марта 2009

Я бы рекомендовал использовать следующую библиотеку PHP UTF-8:

http://sourceforge.net/projects/phputf8

Объединение его с вашим приложением ослабляет требования вашего приложения, не требуя расширения mbstring, но вы все равно получаете строковые функции UTF-8.

...