PHP エクステンションでの引数の受取り方
PHP エクステンションでの引数の扱い方
PHP エクステンションで自前の関数を作った場合、当然ながら何らかのデータを PHP スクリプトから受け取りたい場合があります。 また、処理内容によって適切な戻り値も返すことができないといけません。
まずは、引数の受け取り方をみてみましょう。
引数の受け取り方
PHP エクステンションにて、引数の数を受け取るためには ZEND_NUM_ARGS() マクロを利用します。
引数を解析するための関数として、次の二つの関数が利用可能です。
int zend_parse_parameters( int num_args TSRMLS_DC, char *type_spec, ... ); int zend_parse_parameters_ex( int flags, int num_args TSRMLS_DC, char *type_spec, ...);
TSRMLS_DC は ZTS (Zend Thread Safety) と非 ZTS の両方に対応するために定義されているマクロです。
TSRM はスレッドセーフリソースマネージャ (Thread Safe Resource Manager)、LS はローカルストレージ (Local Storage) を意味しています。
それぞれのバージョンに対応するビルドに対応するために、以下のようにいくつかマクロが定義されています。
TSRMLS_C tsrm_ls
TSRMLS_D void ***tsrm_ls
TSRMLS_CC , tsrm_ls
TSRMLS_DC , void ***tsrm_ls
zend_parse_parameters と _ex の違いは第一引数でフラグを受け取るかどうかだけです。 ここでは zend_parse_parameters のみに着目します。
第一引数はパラメータの数です。これは前述の通り ZEND_NUM_ARGS() マクロで取得できます。
ポイントは第二引数の type_spec です。
type_spec に、下記のような指定文字 (specification character) と指定修飾子 (specification modifier) を記述することによって、どのようなパラメータを期待しているのか記述します。
|
|
例1: 例えば文字列をひとつ受け取る場合は、次のようにします。
ZEND_FUNCTION(keicode_param1) { int argc; int arg_len; char *arg = NULL; argc = ZEND_NUM_ARGS(); if( FAILURE == zend_parse_parameters( argc TSRMLS_CC, "s/", &arg, &arg_len ) ) { return; } OutputDebugString( arg ); }
文字列をひとつ受け取りたいだけなのですが、s を指定する場合は、文字列へのポインタに加えて、 その長さを受け取るための整数の変数の参照も渡す必要があります。そのため、zend_parse_parameters には &arg と &arg_len の二つを渡しています。
上の関数を次のように呼ぶと、以下のスクリーンショットのようにデバッグトレースに、 確かに引数で渡された文字が表示されました。
<?php keicode_param1( 'Hello!' ); ?>
例2: 第一引数と第二引数それぞれに、文字列と倍精度実数 (double) を受け取り、第二引数の double はオプションにする場合は、以下のようにします。
int argc; int arg_len; char *arg = NULL; double dbl = 123.0; argc = ZEND_NUM_ARGS(); if( FAILURE == zend_parse_parameters( argc TSRMLS_CC, "s/|d", &arg, &arg_len, &dbl ) ) { return; }