demolog

備忘録. 雑なあまりにも雑な

PHP+Apacheで日本語正規表現が動かないケース

はじめに

PHP5.6系 + Apache2.2系で日本語正規表現が動かない問題があった。 その時の調査と対処について備忘録。 (PHP7系との組み合わせは未検証)

現象

画面上から以下のカタカナチェックがfalseを返している。

preg_match("/^[ァ-ヶー]+$/u", "テスト");

調査内容

PHP5.6のビルド

pcreは8.12を使用

#! /bin/sh
#
# Created by configure

'./configure' \
'--prefix=/usr/local/php5.6.12' \
'--with-apxs2=/usr/local/httpd2/bin/apxs' \
'--with-config-file-path=/etc/php5.6.12' \
'--with-config-file-scan-dir=/etc/php5.6.12/php.d' \
'--enable-mbstring' \
'--enable-mbregex' \
'--with-mysql=/usr/local/mysql' \
'--with-mcrypt' \
'--with-curl' \
'--with-iconv' \
'--enable-exif' \
'--enable-sockets' \
'--with-gd' \
'--with-openssl' \
'--with-png-dir=/usr/lib' \
'--with-jpeg-dir=/usr/lib' \
'--with-pdo-mysql=/usr/local/mysql' \
'--with-pcre-regex=/usr/local/pcre8.12' \
'--with-pcre-dir=/usr/local/pcre8.12' \
'--with-xsl' \
'--with-zlib' \
'--with-bz2' \
"$@"

そこから「make test」すると、以下のテストに失敗した

Bug #37911 (preg_replace_callback ignores named groups) [ext/pcre/tests/bug37911.phpt]
preg_grep() 2nd test [ext/pcre/tests/grep2.phpt]
preg_match() flags 3 [ext/pcre/tests/match_flags3.phpt]

→この時点のビルドで、画面上でのカタカナチェック通らず

PCREを最新にアップデート

PHP5.6はPCRE8.37がバンドルされている。(参照) ただ --with-pcre-regexが未指定だとmakeでこけてしまったので別途インストール。

PCREインストール手順

# ./configure --prefix=/usr/local/pcre8.37 --enable-utf8 --enable-unicode-properties
# make
# make install

PCREインストール後、PHP再ビルド

#! /bin/sh
#
# Created by configure

'./configure' \
'--prefix=/usr/local/php5.6.12' \
'--with-apxs2=/usr/local/httpd2/bin/apxs' \
'--with-config-file-path=/etc/php5.6.12' \
'--with-config-file-scan-dir=/etc/php5.6.12/php.d' \
'--enable-mbstring' \
'--enable-mbregex' \
'--with-mysql=/usr/local/mysql' \
'--with-mcrypt' \
'--with-curl' \
'--with-iconv' \
'--enable-exif' \
'--enable-sockets' \
'--with-gd' \
'--with-openssl' \
'--with-png-dir=/usr/lib' \
'--with-jpeg-dir=/usr/lib' \
'--with-pdo-mysql=/usr/local/mysql' \
'--with-pcre-regex=/usr/local/pcre8.37' \
'--with-pcre-dir=/usr/local/pcre8.37 ' \
'--with-xsl' \
'--with-zlib' \
'--with-bz2' \
"$@"

ここで「make test」すると、上記のテストが通った。

→この時点のビルドで、画面上でのカタカナチェックが通らなかったが、phpコマンド経由で実行すると問題なく通った

Apache側に問題あり?

phpファイルの先頭(<?phpの直後)に書いた所カタカナチェックが通らなかったので、Apache側に問題ありと判断。

Apache側のビルドオプションを確認

#! /bin/sh
#
# Created by configure

CFLAGS="-fPIC -O3 -DUSE_MMAP"; export CFLAGS
"./configure" \
"--prefix=/usr/local/httpd2" \
"--with-mpm=prefork" \
"--enable-ssl=static" \
"--enable-rewrite" \
"--enable-mods-shared=most" \
"CFLAGS=-fPIC -O3 -DUSE_MMAP" \
"$@"

pcreの指定はないが、configureのオプションには--with-pcreが指定可能である。 --with-pcreを指定してApache再ビルドしてインストール。

#! /bin/sh
#
# Created by configure

CFLAGS="-fPIC -O3 -DUSE_MMAP"; export CFLAGS
"./configure" \
"--prefix=/usr/local/httpd2" \
"--with-mpm=prefork" \
"--enable-ssl=static" \
"--enable-rewrite" \
"--with-pcre=/usr/local/bin/pcre-config" \
"--enable-mods-shared=most" \
"CFLAGS=-fPIC -O3 -DUSE_MMAP" \
"$@"

Webサーバーを再起動して確認。

→画面上でのカタカナチェック通った ApachePHPで認識しているPCREに違いがあった

最後に

  • 原因特定に時間がかかった
  • PHPApacheで見ているPCREが違うのは怖い