PHP拡張でクラス実装がよくわからん

PHPのmingモジュール等を参考に試行錯誤しているのだけども、PHP拡張でクラスを実装するのがよくわからん。
マニュアルもあまりないし。

準備

# ./ext_skel --extname=hello

で hello というモジュールを作ったとする。

実装

php_hello.h を変更。以下を追加。 [c num=1] PHP_METHOD(hello, __construct); PHP_METHOD(hello, taro); PHP_METHOD(hello, jiro);[/c]

hello.c を変更。 static int le_hello の後ろに以下を追加。 [c num=1] static zend_class_entry hello_class_entry_ptr; static void destroy_Hello_resource(zend_rsrc_list_entry resource TSRMLS_DC);[/c] hello_functions はこのように修正。 [c num=1]zend_function_entry hello_functions[] = { PHP_FE(confirm_hello_compiled, NULL) PHP_ME(hello, construct, NULL, 0) PHP_ME(hello, taro, NULL, 0) PHP_ME(hello, jiro, NULL, 0) {NULL, NULL, NULL} };[/c] 初期化。 [c num=1] PHP_MINIT_FUNCTION(hello) { zend_class_entry hello_class_entry; INIT_CLASS_ENTRY(hello_class_entry, "Hello", hello_functions); hello_class_entry_ptr = zend_register_internal_class(&hello_class_entry TSRMLS_CC); le_hello = zend_register_list_destructors_ex( destroy_Hello_resource, NULL, "Hello", module_number ); return SUCCESS; }[/c] 実際に処理するところ。
コメントは愛嬌(なにそれ)。 [c num=1] PHP_METHOD(hello,
construct) { int ret = zend_list_insert(NULL, le_hello); object_init_ex(getThis(), hello_class_entry_ptr); // add_property_resource(getThis(), "hello", ret); // zend_list_addref(ret);

printf("hello->_construct\n");

} PHP_METHOD(hello, taro) { printf("hello->taro\n"); } PHP_METHOD(hello, jiro) { printf("hello->jiro\n");

} static void destroy_Hello_resource(zend_rsrc_list_entry *resource TSRMLS_DC) { printf("hello->destory\n"); }[/c]

確認

テスト用のPHPコード。 [php num=1] <?php dl('hello.so'); $obj = new Hello(); $obj->taro(); $obj->jiro();[/php] 結果。

# php test.php
hello->_construct
hello->taro
hello->jiro
hello->destory

結論

なんとなくわかったこと。

  • クラスメソッドPHP_ME、PHP_METHODを使うらしい。
  • INIT_CLASS_ENTRY、zend_register_internal_classでクラスを定義。
  • zend_register_list_destructors_exでデストラクタ時の処理を設定できるらしい。

あまりよくわからないこと。

  • インスタンスをどうやって扱うのかよくわからん。
  • ってかほとんどよくわからん。

参考にしたページ

【PHPext】PHP拡張モジュールの作成
PHP Extension を作ろう第1回 - まずは Hello World