| | ユーザフォーラムで議論/質問 | マニュアル検索 | ハイライト | ハイライトオフ | ポータル | php spot |
関数の作成拡張モジュールの主要な要素のひとつが、 PHP のユーザー空間にエクスポートする関数です。 オブジェクト指向の拡張モジュールを書こうとしている場合でも、 この章を読んでおくことをおすすめします。 ここにある情報の大半はメソッドを書く場合にもあてはまるからです。 ext_skel で新しい基盤を作った後などに新しい関数を追加するには、 その内容を C の関数として実装して、 作った関数のエントリを拡張モジュールの関数テーブルに追加します。 関数のエントリには、引数情報の構造体へのポインタを含めることができます。 パラメータを参照で渡したり参照を返したりするのでない限り、 引数情報を渡すことは必須ではありません。しかし、情報を渡しておけば PHP の Reflection API からアクセスできるようになります。以下の例でわかるとおり、 パラメータはそのまま実装へ渡されるわけではなく スタックに積んで渡されます。 このスタックは関数の実装によってチェックされます。 関数の実装は直接の情報源とはなりません。 例1 関数をひとつ持つ最小限の PHP 拡張モジュール /* {{{ proto void hello_world()
Do nothing */
PHP_FUNCTION(hello_world)
{
}
/* }}} */
/* {{{ arginfo_hello_world */
ZEND_BEGIN_ARG_INFO(arginfo_hello_world, 0)
ZEND_END_ARG_INFO()
/* }}} */
/* {{{ demo_functions */
function_entry demo_functions[] = {
PHP_FE(hello_world, arginfo_hello_world)
{NULL, NULL, NULL}
}
/* }}} */
/* {{{ demo_module_enry */
zend_module_entry demo_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"demo",
demo_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
"1.0.0",
#en
STANDARD_MODULE_PROPERTIES
}
/* }}} */
この例では、上で説明した要素やモジュールの構造を確認することができます。 この構造に見覚えがない場合は zend_module 構造体 を見直してみましょう。 この拡張モジュールの最初の部分は、実際の実装です。 慣習として、エクスポートする関数の前には二行のコメントをつけることになっています。 コメントには、利用者向けの関数プロトタイプと 一行での短い説明を記述します。
PHP の異なるバージョン間でソースコードの互換性を保持するため、
関数の宣言を
void zif_hello_world(int ht, zval *return_value, zval **return_value_ptr,
zval *this_ptr, int return_value_used TSRMLS_DC)
{
}
ユーザー空間にエクスポートする関数や C の別の関数との名前の衝突を避けるため、
エクスポートする関数の C のシンボルには先頭に
先ほども説明したように、上の関数は単に NULL を返すだけで他に何もしません。 PHP 側からこの関数をコールするときには任意の数のパラメータを指定することができます。 もう少し実用的な関数は、大きく四つの部分にわけることができます。
場合によってはこれらの順序は前後することもあります。 特に最後のふたつは一緒になってしまうことも多いでしょう。 しかし、この順序を守っておくほうがよいでしょう。 例2 単純な関数 /* {{{ proto void hello_world(string name)
Greets a user */
PHP_FUNCTION(hello_world)
{
char *name;
int name_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
return;
}
php_printf("Hello %s!", name);
RETURN_TRUE;
}
/* }}} */
この関数は、先ほどの各部分を示したものです。
まずは最後の行から見ていきましょう。
最後の行にあるマクロ
PHP のスレッドセーフなリソースマネージャーとの互換性を考慮して、
スレッドコンテキストの後には、想定しているパラメータを宣言します。
各パラメータが文字列内の一文字として表され、それが型を示します。
この例では文字列のパラメータを想定しているので、型の指定は単純に
最後に渡すのは一つあるいは複数の C 変数へのポインタで、
ここには変数の値やその他の情報が格納されます。
今回のような文字列の場合は、
NULL 終端の実際の文字列を表す すべての型指定子とそれに対応する C の型については、ソース配布物の中にある » README.PARAMETER_PARSING_API に説明があります。 中でも重要な型について次の表にまとめました。
|
|
各種マニュアル:
PHPマニュアル |
PEARマニュアル |
Smarty(英語)マニュアル |
PHP-GTKマニュアル |
「関数の作成」をGoogle検索
|