2007年3月8日木曜日

(FreeBSD) php-5.2.1にて"Warning: preg_split() [function.preg-split]: Compilation failed: lookbehind assertion is not fixed length at offset ..."と表示される

PHPど素人ですので詳しいことは理解できてないのですが、FreeBSD 6.2-STABLEで、php-5.2.1、およびその他いろいろを使ってみたところ、別の環境では動いていたはずのPHPスクリプトが

Warning: preg_split() [function.preg-split]: Compilation failed: lookbehind assertion is not fixed length at offset 7 in /usr/local/share/pear/DB/common.php on line 807

とか表示されて、動かなくなってしまいました。



ネットで検索すると、同じような話題がでてて、しかも気のせいかFreeBSD 6の場合が多いような・・・



検索しても解決方法が見つからず、手元のいくつかあるFreeBSDマシンで、手当たりしだいに試して、問題をしぼりこんでみたところ・・・

php-*、pecl-*を、いったんすべて削除し、新規インストールしたら、正常になりました。

というわけで、なんともUnixっぽくない解決方法で申し訳ない。



この問題は、どうも、以前php4をインストールしていた環境を、portupgradeでphp5にアップデートしたときに、起きるようになったみたいです。「portupgrade -o lang/php5 php4-なんとか」みたいなことをやったんですが・・・



これ、もしかすると、「pecl-*」がアップデートされていなかったのが原因かもしれません。
だから、「portupgrade -f /var/db/pkg/pecl-*」するだけで直るかも???



実は、以下のように、既存のPHPファイルを退避させておいてから、新規インストールと同等のことをやってみました。



# mv /usr/local/include/php /usr/local/include/php-
# mv /usr/local/lib/php /usr/local/lib/php-
# mkdir /usr/local/etc/OLD
# mv /usr/local/etc/php* /usr/local/etc/OLD/
# portupgrade -f /var/db/pkg/php*



途中で、peclがうんたらというエラーで止まったこと。および、



/usr/local/lib/php/20060613/filter.so
/usr/local/lib/php/20060613/json.so
/usr/local/lib/php/20060613/fileinfo.so



といったファイルは、



pecl-filter-0.11.0
pecl-json-1.2.1
pecl-fileinfo-1.0.4



でインストールされているのですが、これらの*.soファイルは古いままだったこと。この2点から。peclが原因だったのかなぁ~と思った次第です。



☆ ☆ ☆ ☆ ☆ ☆ 



問題のコード/usr/local/share/pear/DB/common.phpも、ちょっと調べてみました。



$tokens   = preg_split('/((?<!\\\)[&?!])/', $query, -1,
                       PREG_SPLIT_DELIM_CAPTURE);



というやつなんですが・・・こんな正規表現、わけわかりません(笑)。



php-5.2.1/ext/pcre/pcrelib/doc/pcre.txt



を見ると、Lookbehind assertionsというものだそうで、 “(?<=” と “)”の間にあるパターンにマッチしない、という表現らしいです。[^\\]じゃダメなのかしらん?



わかりやすくするために分解して書くと



'/((?<!\\\)[&?!])/'





(  (?<! \\\ )  [&?!]  )



ということ。一番外側のカッコは、preg_splitで利用するために使うつもりみたいです。



ところで、はてな、「\\\」って何ですかね。



http://www.php.net/manual/ja/reference.pcre.pattern.syntax.php
によると

そのため、正規表現 \\ を使用して \ とマッチさせたい場合は PHP のコード内では "\\\\" あるいは '\\\\' と記述する必要があります。

とあるので、「\\\\」の間違いなんじゃないか?と思ってしまったのですが・・・



好奇心から、試してみると、



  • \\\\」に変えても、意図どおり動いてるっぽい


  • 「\\」にすると、エラー。「\)」となって、閉じカッコがエスケープされてしまって、閉じカッコが足りなくなるから。


ま、いいかっ! 気にしない 気にしない





(2007-3-14)
なんか知らないうちにまた例のエラーメッセージ(warningだけど、うごかねーよ・・・)が出るようになってました。エラーがでても、もう1回実行すると、正常に動作したりするんですけど。
うーん。



0 件のコメント:

コメントを投稿