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_ME、PHP_METHODを使うらしい。
- INIT_CLASS_ENTRY、zend_register_internal_classでクラスを定義。
- zend_register_list_destructors_exでデストラクタ時の処理を設定できるらしい。
あまりよくわからないこと。
- インスタンスをどうやって扱うのかよくわからん。
- ってかほとんどよくわからん。
参考にしたページ
【PHPext】PHP拡張モジュールの作成
PHP Extension を作ろう第1回 - まずは Hello World