PHP 拡張のコンパイルで PHP_FE_END undeclared here
初めに断っておくと、古い PHP を残してしまう悪しきドキュメントです。
# とはいえ、PHP 5.3.x の x を固定にしてセキュリティパッチで延命する事もありそうなので。
はじめに
たまたま、この PHP 拡張を試そうとして*1思い出したのですが、
(特に野良の) PHP拡張をコンパイルする時に結構な頻度で PHP_FE_END でエラーになります。
/home/yoya/git/php-xz/xz.c:69: error: ‘PHP_FE_END’ undeclared here (not in a function)
これへの模範的な解答は、 PHP 5.4 か、ダメでも PHP 5.3.x の最新版 x に今すぐ上げろ! ですが、そうすぐには上げられない人向けに、以下に原因と対策です。
エラーの原因
PHP 拡張で zend_function_entry の終端は、PHP 5.3.6 までは
zend_function_entry xxx_functions[] = { PHP_FE(xxx_yyy, arginfo_xxx_yyy) <略> {NULL, NULL, NULL}
という書き方でしたが、PHP 5.3.7 から
zend_function_entry xxx_functions[] = { PHP_FE(xxx_yyy, arginfo_xxx_yyy) <略> PHP_FE_END
このように変わりました。
要するに
PHP 5.3.7 以降用に書かれた PHP 拡張のプログラムを
PHP 5.3.6 以前の環境で build しようとすると、
PHP_FE_END undeclared のエラーが出ます。
PHP のヘッダ
PHP_FE_END の定義は、
php-5.3.7/Zend/zend_API.h:#define ZEND_FE_END { NULL, NULL, NULL, 0, 0 } php-5.3.7/main/php.h:#define PHP_FE_END ZEND_FE_END
PHP 5.3.6 と PHP 5.3.7 で grep すると、5.3.7 で定義が追加された事が分かります。
yoya@sakura:~/src/php$ grep -r PHP_FE_END php-5.3.6 | grep ".h:" yoya@sakura:~/src/php$ grep -r PHP_FE_END php-5.3.7 | grep ".h:" php-5.3.7/main/php.h:#define PHP_FE_END ZEND_FE_END yoya@sakura:~/src/php$
対策
真面目にやるならバージョンを見て切り替えをする王道を進むのが良いでしょう。
#if (defined(PHP_VERSION_ID) && PHP_VERSION_ID >= 50307) PHP_FE_END #else {NULL, NULL, NULL} #endif
-
- PHP_VERSION_ID は 5.2.7 で導入されたものなので defined でのチェックが必要。
あと、身も蓋もない方法ですが自分で define しても勿論コンパイル出来ます。
何処にも commit しないコードならこんな感じで手抜きするのも手です。
#ifndef PHP_FE_END #define PHP_FE_END {NULL, NULL, NULL} #endif PHP_FE_END
筋は悪いですけど、あと20秒で build してインストールしないと世界が滅びる!
なんてシチュエーションがもしあれば使えば良いと思います。