PHP の pcre 設定

スポンサーリンク

概要

preg_match, preg_replace などで使用する PHP の正規表現は、 PCRE(Perl Compatible Regular Expression)を使っています。
この PCRE ですが、PHP-5.2 より前とそれ以降では挙動が異なるので注意が必要です。

挙動の違い

PHP-5.2 以降では php.ini で設定可能な項目として下記が追加されました。

  • pcre.backtrack_limit
  • pcre.recursion_limit

それぞれ名称の通り、バックトラック処理/再帰処理の制限値です。
これらの制限に引っかかった時にはマッチングをあきらめてしまうようで、結果として preg_match であれば 0、preg_replace であれば null が返ってきます。

従って、PHP-5.2 より前のバージョンではこれらの制限がなかったようなので正しく動いていた処理が、PHP-5.2 以降で動かすと正しく動かなくなる、、、といったタチの悪いことが発生します。
しかも、例外が発生するとかではなく、単純にマッチしなかったかのような挙動なので、問題として見つけることが非常に困難です。

対処方法

この問題が起きてしまった時の対処方法ですが、メモリ的に問題がないのであれば単純に php.ini で明示的に設定をして、設定値を増やすことで解消します。

pcre.backtrack_limit=500000
pcre.recursion_limit=500000

Smarty で発生

これは自分だけかもしれませんが、この問題は今のところ Smarty のテンプレート内の処理でしか起きたことがありません。
もしかしたら、Smarty はこの問題が起きやすい作りになっているのかも。。。

pcre.jit

php.ini で設定可能な PCRE 項目として、pcre.jit という項目があります。
これは、PCRE の just-in-time コンパイラを利用するかどうかのフラグです。
一度正規表現をコンパイル後に利用すると、繰り返しマッチが非常に高速化されます。
ただ、経験上意味不明なエラーが出たこともあったのであまりいいイメージは無かったのですが、下記の情報によると性能的に非常に有用ですので、基本的には無効にするのは良くなさそうです。

https://speakerdeck.com/hanhan1978/pcre-pcre-jit-and-php

デフォルトで pcre.jit は有効なので、特別な理由がない限りはそのままで良さそうです。

コメント

タイトルとURLをコピーしました