Последнее обновление:
Об ошибке функции mb_ereg_replace (РНР)
Вроде бы, где-то в недрах php.net дается указание на то, что функция mb_ereg_replace()
является устаревшей и не рекомендуется к применению. Однако, не указано, почему.
Функция mb_ereg_replace() в языке РНР выполняет (точнее, должна выполнять) замену по регулярному выражению. Как правило, она это выполняет. Но, в том то и дело, что КАК ПРАВИЛО. А не всегда. В некоторых случаях она способна на вольности. Рассмотрим простейший код, иллюстрирующий сказанное:
<?php
mb_internal_encoding('utf-8');
mb_regex_encoding('UTF-8');
$x = "Сим\&вол & &амперсанда< &";
echo mb_ereg_replace('&', '&', $x).'<br/>';
file_put_contents('mb-ereg-replace-PHP-rezult.html', mb_ereg_replace('&', '&', $x). PHP_EOL);
echo str_replace('&', '&', $x).'<br/>';
file_put_contents('mb-ereg-replace-PHP-rezult.html', str_replace('&', '&', $x). PHP_EOL, FILE_APPEND);
echo preg_replace('/&/', '&', $x).'<br/>';
file_put_contents('mb-ereg-replace-PHP-rezult.html', preg_replace('/&/', '&', $x). PHP_EOL, FILE_APPEND);
$x = mb_convert_encoding($x, 'cp1251', 'utf-8');
echo mb_ereg_replace('&', '&', $x).'<br/>';
file_put_contents('mb-ereg-replace-PHP-rezult.html', mb_ereg_replace('&', '&', $x). PHP_EOL, FILE_APPEND);
echo str_replace('&', '&', $x).'<br/>';
file_put_contents('mb-ereg-replace-PHP-rezult.html', str_replace('&', '&', $x). PHP_EOL, FILE_APPEND);
echo preg_replace('/&/', '&', $x).'<br/>';
file_put_contents('mb-ereg-replace-PHP-rezult.html', preg_replace('/&/', '&', $x). PHP_EOL, FILE_APPEND);
Вот демонстрация результата его работы. Вот что сохранилось в файле. Как видно в 4-й строке, функция mb_ereg_replace() решила посвоевольничать и НЕ преобразовала в <
амперсанд в его html-сущность &
. Любопытно, что отказалась она это делать только тогда, когда исходная строка, в которой делались преобразования, была закодирована в кодировке cp1251 (windows-1251). Тогда как с utf-8 эта функция работает нормально, все амперсанды преобразуются, как полагается.
Но, самое плохое даже не в этом. А в том, что автор статьи столкнулся с ситуацией, в которой функция mb_ereg_replace() отказалась заменить на &
... одиночный амперсанд, встречающийся в строке (собственно, именно это и побудило написать статью). К сожалению, здесь этот баг не воспроизвелся. Но, в любом случае, рекомендация такая: функцию mb_ereg_replace()
лучше бы не использовать, так как поведение ее может быть непредсказуемым. И дело тут, как видится, совсем не в стандарте POSIX. И не в том, что регулярное выражение в mb_ereg_replace() обозначается не так, как в preg_replace().
Надо сказать, что с str_replace()
и preg_replace()
подобных проблем не наблюдалось.