preg_match関数の文字数制約
先に結論を申し上げますと以下の通りです。
-
preg_match
関数で検索対象とする文字列の長さにはある程度制約がある模様 - 具体的に何文字まで・何バイトまでという定義はない、というか文字列の構成で変わっている気もする
preg_match
関数とは、PHPで正規表現を行い、その結果を取得する関数。
詳しい事は公式のマニュアルをご覧いただくとして。
先日、Base64エンコードした文字列を受け取ってデコードし、ファイルとしてサーバに保存する処理を書いていたところ、どういうわけか一部のファイルだけデコードに失敗することがあり、調査していったところ判明しました。
何でBase64のデコードにpreg_match関数が関係あったのかは後で説明するとして、探していくとどうやら pcre.backtrack-limit
という値が関係しているようでした。
上記によると、この pcre.backtrack-limit
の値が初期値は 1,000,000。
これが具体的にどのように preg_match
関数に関わってくるのかは分かりません。単純に文字数やバイト数ではないような気もしております。再帰処理の数とかその辺かなあ。
いずれにせよ、対策として考えられるのは以下の2通りです。
対策1:正規表現を掛ける箇所以外を捨てる
今回採用したのはこちらでした。
Base64エンコードされた文字列をデコードするにあたり、冒頭にMIME Typeを示す文字列があったらそれを取り除いて base64_decode
関数に掛けるということをしていたので、MIME Typeが出現するであろう冒頭100文字以内を preg_match
関数の対象にすることで、解決できました。
対策2:PHP設定を変える
対策1は、文中のどこにマッチする文言が出てくるか分からないケースでは採用できません。
では正規表現を掛ける文字列を何分割かにするかというと、その分割した境目にマッチさせたい文字列があった場合には検出できなくなります。
そういう場合には pcre.backtrack-limit
自体の定義を ini_set
関数を使って、もしくは php.ini
や .htaccess
への追記で恒久的に変更して、解決できるかもしれません。
試していないので分かりません。
Discussion