【PHPext】PHP拡張モジュールの作成
構築環境:Fedora Core 3, Kernel 2.6.10-1.770, autoconf 2.59, automake 1.9.2, gcc 3.4.2,PHP 4.3.x-dev
PHP拡張モジュール †
長所
- 既存のCのライブラリを使える
- 高速(これはApacheモジュールにしたほうが有利かも)
短所
- プログラミングに時間がかかる
- モジュールの内容を変更するには再コンパイルが必要
普通のPHPerな人間はあんまり使わない。
準備/必要なもの †
- C言語を操れる脳みそ
- autoconf/automake/libtool/gcc
- awk*1
- PHPのsnapshotのコード*2。
手順 †
PHP拡張モジュールを作成する手順は以下のようになります。
プロトタイプファイルとは
モジュールに含まれる関数名を羅列したテキストファイルです。
プロトタイプファイルをext_skelスクリプトで処理すると、コードの基本的な部分が自動生成されます。
- プロトタイプファイルの作成
- ext_skelによる、コードの生成
- config.m4の編集
- configureスクリプトの生成
- コーディング
- コンパイル
サンプル モジュールの作成 †
下記のような関数を含むモジュ-ルを作成してみる。モジュール名は「sample_funcs」とする。
- void omikuji()
- 「daikichi(^-^)」「cyu-kichi(-_-)」「kyo(T_T)」のそれぞれを3分の1の確立で表示する。
- string orz([bool isCapital])
- isCapitalがTRUEなら「Orz」、FALSEなら「orz」と返す。isCapitalは省略可能で、デフォルトは小文字。
プロトタイプの記述(関数の定義ファイル) †
[型] 関数名(引数) [コメント]
型とコメントはオプションです。コードのコメントとして記載されるだけです。
sample_funcs.proto
void omikuji() Return Fortune Telling result. string orz([bool isCapital]) Return orz.
ext_skelによるコードの生成 †
ext_skelスクリプトを動かします。sample_funcsフォルダとコードが自動生成されます。
# cd ext/ # ./ext_skel --extname=sample_funcs --proto=sample_funcs.proto
config.m4の編集 †
config.m4の16、18行目のコメントアウトをはずします(dnlを消す)。
これによりconfigureスクリプトで--enable-sample_funcsと指定することが出来るようになります。
config.m4
16: PHP_ARG_ENABLE(sample_funcs, whether to enable sample_funcs support, 17: dnl Make sure that the comment is aligned: 18: [ --enable-sample_funcs Enable sample_funcs support])
configureスクリプトの生成 †
buidconfスクリプトを動かすとconfig.m4をもとに、自動的にconfigureスクリプトが生成または更新されます。
# cd ../ # ./buildconf
autoheaderがWARNING吐きだすけど、自分のせいじゃないのでとりあえず無視する(笑)*3
using default Zend directory rebuilding configure rebuilding main/php_config.h.in autoheader: WARNING: Using auxiliary files such as `acconfig.h', `config.h.bot' autoheader: WARNING: and `config.h.top', to define templates for `config.h.in' autoheader: WARNING: is deprecated and discouraged. autoheader: autoheader: WARNING: Using the third argument of `AC_DEFINE' and autoheader: WARNING: `AC_DEFINE_UNQUOTED' allows to define a template without autoheader: WARNING: `acconfig.h': autoheader: autoheader: WARNING: AC_DEFINE([NEED_FUNC_MAIN], 1, autoheader: [Define if a function `main' is needed.]) autoheader: autoheader: WARNING: More sophisticated templates can also be produced, see the autoheader: WARNING: documentation.
コーディング †
sample_funcs.cを編集し、実際に関数の中身をコーディングする。
#cd ext/sample_funcs.c #vi sample_funcs.c
rand()、srand()用にstdlib.h, time.hをincludeする。
#include <stdlib.h>
#include <time.h>
/* {{{ proto void omikuji()
Return Fortune Telling result. */
PHP_FUNCTION(omikuji)
{
if (ZEND_NUM_ARGS() != 0) {
WRONG_PARAM_COUNT;
}
srand((unsigned int)time(NULL));
switch (rand() % 3) {
case 0:
php_printf("%s", "daikichi(^-^)");
break;
case 1:
php_printf("%s", "cyu-kichi(-_-)");
break;
default:
php_printf("%s", "kyo(T_T)");
break;
}
/* php_error(E_WARNING, "omikuji: not yet implemented"); */
}
/* }}} */
/* {{{ proto string orz([bool isCapital])
Return orz. */
PHP_FUNCTION(orz)
{
int argc = ZEND_NUM_ARGS();
zend_bool isCapital;
if (zend_parse_parameters(argc TSRMLS_CC, "|b", &isCapital) == FAILURE)
return;
if (isCapital) {
RETVAL_STRING("Orz", 1);
} else {
RETVAL_STRING("orz", 1);
}
/* php_error(E_WARNING, "orz: not yet implemented"); */
}
/* }}} */
各関数の説明はこちら
コンパイル †
configureに--enable-sample_funcsを付けて実行する。
#cd ../../ #./configure --enable-sample_funcs #make
開発中は、make installをしないで、既存のPHP環境は残しておいたほうが無難
動かしてみる †
まずは、phpinfo()にsample_funcsの項目が追加されているか確認する。
#echo '<?php phpinfo() ?>' | ./sapi/cli/php | grep sample_funcs Configure Command => './configure' '--enable-sample_funcs' sample_funcs sample_funcs support => enabled
となっていればOK。なっていなければ、config.m4が間違っているか、configureスクリプト が更新されていないので、チェックしよう。
あとは同様の方法で動作をチェックする。
#echo '<?php omikuji(); ?>' | ./sapi/cli/php #echo '<?php echo orz(); ?> | ./sapi/cli/php #echo '<?php echo orz(TRUE); ?> | ./sapi/cli/php #echo '<?php echo orz(FALSE); ?> | ./sapi/cli/php
参考資料 †
- README.EXT_SKEL 日本語訳 http://catbot.net/doc/ext_skel.html
- Writing extensions http://www.hudzilla.org/phpbook/read.php/20_0_0
&amazon(1411601882, image);