リフレクション情報を設定する
関数作成最後の仕上げとして、リフレクションなどを通じて引数情報が取得できるように設定を行います。この処理は実際の処理とは関係ありませんが、他の人に対して公開する場合などはぜひとも設定しておいた方がよい処理になります。
例えば、以下のようなLong型の引数を2つ取る関数を作成をします。
PHP_FUNCTION(hellofunc_args_num2){ long val1 = 0, val2 = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &val1,&val2) == FAILURE ){ return; } long sum = val1 + val2; RETURN_LONG(sum); }
この関数の引数情報を設定するには、以下のようになります。
ZEND_BEGIN_ARG_INFO_EX(arginfo_num2, 0, 0, 2) // ……(1) ZEND_ARG_INFO(0, long1) // ……(2) ZEND_ARG_INFO(0, long2) // ……(3) ZEND_END_ARG_INFO() // ……(4)
(1)のZEND_BEGIN_ARG_INFO_EXマクロは、以下の4つの引数を取ります。
- 定義名(後で、PHP_FEで設定します)
- 参照渡しを受け取るか
- 戻り値を引数で受け取るか
- 引数の数
(2)、(3)のZEND_ARG_INFOマクロは実際の引数を指定し、以下の2つの引数を取ります。
- 参照渡しを受け取るかで、参照渡しの場合に1にする。
- 引数の変数名(PHP_FEマクロで使用します)
そして、(3)のZEND_END_ARG_INFOマクロで定義を閉じます。
const zend_function_entry hellofunc_functions[] = { : PHP_FE(hellofunc_args_num2, arginfo_num2) // ……(1) : }
最後に関数のエントリとして(1)PHP_FEマクロの第2引数に設定を行えば終了です。これらもPHPのソースを調べれば、たいていの場合は自分が作成したい関数の引数定義と同じような関数がすでにあります。分からない時には、それらのソースを参考にすると、ほとんどのケースでは問題ありません。
最後に
前回と今回で一通りの関数の作成方法を紹介してきました。特に、今回紹介した配列は動的な扱いが簡単にできますので、使い方を覚えておくといろいろと応用ができます。
また、ここでは紹介できませんでしたが、エクステンション側からは実際の引数はすべての型がzval型(PHPではMixed型)として扱うことが可能です。ここまで紹介してきた方法以外にも、実装方法も多数あります。実際に、それらについての詳細を知りたい場合には、PHPのソースを参照していくと良いでしょう。沢山の実装方法がありますので非常に勉強になり、新たな発見がそこからいくつも見つかるのではないかと思います。