■PHPのメジャーバージョンが上がり、5.4.xがリリースされた。文法に手が入るなど、ちょっと大きな変更らしい。現在使っている5.3.xはいずれメンテされなくなるだろうから切り替えておきたい。ただ、ちょっと心配なのは今使っているスクリプトがそのままで通用するかということ。特に今ZBのメッシュネットワークのゲートウェイでPHPからTTYのポートを叩いてZBeeとやりとりしているDIOモジュールが動かなかったりするとデバイスコントロールができなくなってしまう。DIOはPECLモジュールになっていて……PHP5.4.x向けに改修がかかっていないような。
まずは普通にPECLでインストールしてみる。
# pecl install dio-0.0.5
downloading dio-0.0.5.tgz ...
Starting to download dio-0.0.5.tgz (18,754 bytes)
......done: 18,754 bytes
12 source files, building
:
:
:
/tmp/pear/temp/dio/dio.c: In function 'zif_dio_open':
/tmp/pear/temp/dio/dio.c:99:54: error: 'struct _php_core_globals' has no member named 'safe_mode'
/tmp/pear/temp/dio/dio.c:99:103: error: 'CHECKUID_CHECK_MODE_PARAM' undeclared (first use in this function)
/tmp/pear/temp/dio/dio.c:99:103: note: each undeclared identifier is reported only once for each function it appears in
make: *** [dio.lo] Error 1
ERROR: `make' failed
…エラーになった。
エラーの原因になっているのは'safe_mode'というシンボル定義が無いことだけど、これはPHP5.4.xになり、safe_modeが無くなったため。
grepしてみると、dio.cとdio_stream.cに問題のコーディングがあり、いずれも同じパターンを持っている。本処理前のチェックロジックの中で、機械的に'(PG(safe_mode) && !php_checkuid(filename, mode, CHECKUID_CHECK_MODE_PARAM))'という条件式が使われている。この条件式は本来のチェックに対する追加条件になっているようで、いずれも「safe_modeであるなら」というロジックになっている。PHP5.4.xではそのsafe_modeそのものがなくなるのだから、このチェックロジックは不要なので、条件文から外した。試しにコンパイルするとエラー無く通る。ただし、ダウンロードしたソースに手元でパッチを当てているのでpeclコマンドは使えない。
手元でコンパイルし、インストールする手順はPHPのサイトに「phpizeで共有PECL拡張モジュールをコンパイルする方法」として公開されている。ソースファイルを修正したDIOのディレクトリに移動して、phpizeコマンドを実行する。
$ cd dio-0.0.5
$ phpize
configureファイルが作られるので、実行して、makefileを生成させる。prefixなどは適当に。
$ ./configure --enable-dio
動作確認のために複数のPHPをインストールしている場合はmakefileの中にあるphp関連のディレクトリ、EXTENSION_DIRやPHP_EXECUTABLEなどを確認しておいた方がいいかもしれない。makefileに問題なければmakeし、インストールする。
$ make
$ make install
インストールされたモジュールはphp.iniで指定した拡張モジュール用ディレクトリではなく、makefileのEXTENSION_DIRに配置されているので、コピーするなり、リンク張るなりする。
最後にphp.iniでExtension=dio.soを有効にし、
$ php -v
など実行して拡張モジュールのローディングにエラーが出なければOK。apacheモジュールとして取り込んでいる場合はapacheも再起動する。
動作確認してみると、殆ど問題ありませんでした。ただ、PHP5.4.xで関数への引数に参照渡しが使えなくなり、その関係でシンタックスエラーが出ました。こちらで使っているスクリプトだと、プロセス間通信に使っているmsg_receiveの引数がエラーになりました。もともと参照渡しになっている関数ですが、この参照渡しを通常の引数渡しに直してやるとエラーもなく、機能にも問題ありませんでした。
参照渡しが廃止になったことはマニュアルにはまだ反映されていないので、これはちょっとまずい状態のような気がします。いずれ対応されると思いますが。