Функции preg_replace, preg_match_all и preg_match не работают с длинными строками
При попытке искать в PHP по регулярным выражениям с помощью функций preg_replace preg_match_all и preg_match (или других функций поиска по регулярным выражениям) может возникнуть следующая проблема: строка по которой выполняется поиск точно содержит подстроку, совпадающую с искомым шаблоном; но вместо вывода совпавших строк, функция ничего не находит. Какие либо ошибки также не выводятся.
Начиная с PHP 5.2, введено ограничение на размер текста, к которому могут быть применены функции PCRE. По умолчанию максимальный размер текста, для которых работают функции PCRE составляет 100k. При превышении этого лимита не будет выведено никаких сообщений об ошибке, но при этом также не будет ничего найдено.
Как увеличить лимит строки для поиска по регулярным выражениям
Возникает логичный вопрос, как увеличить лимит максимальной длины строки для функций PCRE.
Можно увеличить максимальную длину строки для поиска по регулярным выражениям в PHP в файле php.ini.
Для начала найдите этот файл:
locate php.ini
Пример расположения файла в дистрибутивах Linux основанных на Debian (Ubuntu, Linux Mint, Kali Linux) — обратите внимание, расположение файла зависит от версии PHP:
/etc/php/8.2/apache2/php.ini
Пример расположения файла для дистрибутивов Linux основанных на Arch Linux (Manjaro, BlackArch):
/etc/php/php.ini
Откройте файл php.ini с правами пользователя root:
sudo gedit /etc/php/php.ini
Найдите строку с pcre.backtrack_limit:
;pcre.backtrack_limit=100000
Раскомментируйте эту строку (удалите точку с запятой в начале строки) и установите желаемый лимит:
Сохраните и закройте этот файл.
Если вы запускаете PHP скрипты в командной строке, то для вас внесённые изменения должны вступить в силу немедленно.
Если вы запускаете скрипты с помощью веб-сервера Apache, то необходимо перезапустить эту службу.
Для перезапуска службы Apache в дистрибутивах на основе Debian (Ubuntu, Linux Mint, Kali Linux) выполните следующую команду:
sudo systemctl restart apache2.service
Для перезапуска службы Apache в дистрибутивах на основе Arch Linux (Manjaro, BlackArch) выполните следующую команду:
sudo systemctl restart httpd.service
После этого изменения должны вступить в силу.
Если ваша проблема не решена, то попробуйте увеличить лимит на большее значение.
Безопасно ли увеличивать pcre.backtrack_limit
Имеется мнение, что увеличение pcre.backtrack_limit может привести к переполнению стека (stack overflow) и аварийной остановке службы Apache.
Видимо, эти баги уже устранены, поскольку в современных версиях PHP и Apache никаких проблем после увеличения pcre.backtrack_limit я не наблюдаю.
Напротив, это разрешило мою проблему с поиском по регулярным выражениям в очень длинных строках и очень больших текстовых файлах.
Связанные статьи:
- Ошибка «No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php/php8.1-fpm.sock (*:80) failed» (РЕШЕНО) (57.6%)
- Как в PHP 8 показать все ошибки (56.9%)
- Как получить User Agent в PHP. Как настроить browscap.ini (56.1%)
- Ошибка «Cannot load modules/libphp7.so» (РЕШЕНО) (51.5%)
- Ошибка «Unable to load dynamic library 'xmlrpc.so'» (РЕШЕНО) (51.5%)
- Бесплатное получение и настройка автоматического продления действительных сертификатов SSL (RANDOM - 23.4%)