TITLE:PHP extension の作り方 #contents - swfed extension の作成メモ * 準備 [#tfe940d3] ** ディレクトリ作成 [#u6ffe968] $ cd php-x.x.x/ext $ ./ext_skel --extname=swfed $ cd swfed ** configure 作成 [#u08733bc] - 必要に応じて後でやり直せる (.c ファイルを増やすとか) $ vi config.m4 PHP_ARG_ENABLE から3行のコメントを外す dnl PHP_ARG_ENABLE(swfed, whether to enable swfed support, dnl Make sure that the comment is aligned: dnl [ --enable-swfed Enable swfed support]) ↑これらの dnl を消す PHP_NEW_EXTENSION に追加するファイルを指定する 前) PHP_NEW_EXTENSION(swfed, swfed.c, $ext_shared) 後) PHP_NEW_EXTENSION(swfed, swfed.c swf_object.c, $ext_shared) ↑空白 $ phpize $ ./configure $ make * クラス実装 [#ge766403] ** 定義 (php_swfed.h) [#c087b34f] - クラスエントリ作成 static zend_class_entry *swfeditor_ce; - クラスメソッド定義 PHP_METHOD(swfed, __construct); PHP_METHOD(swfed, input); ** 実装 (swfed.c) [#k9e53596] - ファンクションエントリ作成 zend_function_entry swfed_functions[]= { <略> PHP_ME(swfed, __construct, NULL, 0) - モジュール初期化でクラス設定 PHP_MINIT_FUNCTION(swfed) <略> zend_class_entry ce; INIT_CLASS_ENTRY(ce, "SWFEditor", swfed_functions); swfeditor_ce = zend_register_internal_class(&ce TSRMLS_CC); le_swfed = zend_register_list_destructors_ex(free_swfed_resource, NULL, "SWFEditor", module_number); zend_declare_property_stringl(swfeditor_ce, "swf_object", strlen("swf_object"), "", 0, ZEND_ACC_PUBLIC); - ファンクション実装 PHP_METHOD(swfed, __construct) { swf_object_t *swf = swf_object_open(); int ret; ret = zend_list_insert(swf, le_swfed); object_init_ex(getThis(), swfeditor_ce); add_property_resource(getThis(), "swfed", ret); zend_list_addref(ret); } -- クラス内部データも swfed のラベルで保存。 PHP_METHOD(swfed, input) { <略> *** クラス内部データの取り方 (というより Zend に登録したデータの一般的な引き出し方) [#z6cb27c1] zend_read_property zend_hash_find Z_LVAL_PP zend_list_find *** 引数の取り方 (string 型) [#d669e144] zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) *** 引数の取り方 (可変長引数) [#i9068654] - ext/interbase/ibase_blobs.c から引用 switch (ZEND_NUM_ARGS()) { default: WRONG_PARAM_COUNT; case 1: if (FAILURE == zend_parse_parameters(1 TSRMLS_CC, "s", &blob_id, &blob_id_len)) { RETURN_FALSE; } break; case 2: if (FAILURE == zend_parse_parameters(2 TSRMLS_CC, "rs",&link, &blob_id, &blob_id_len)) { RETURN_FALSE; } break; } *** 返り値 [#wa6cd1b0] - 例 RETURN_{TRUE|FALSE} RETURN_LONG(l) RETURN_STRINGL(s, l, dup) - 配列の返し方 -- [http://devlog.agektmr.com/wiki/index.php?PHP%2FExtension%20Writing%20Part%20II%20Parameters%2C%20Arrays%2C%20and%20ZVALs Extension Writing Part II: Parameters, Arrays, and ZVALsの翻訳] * 参考 [#g26dae43] - PHP拡張モジュールでクラス定義 -- http://diary.eth.jp/?date=20080131#p01 - メモリ管理 -- http://psa.ange.ac/zenddoc/zend.layout.memory-management.html - PHP拡張でクラス実装がよくわからん -- http://www.developer0000.jp/2007/01/07/1310/ ○ クラスメソッドはPHP_ME、PHP_METHODを使うらしい。 ○ INIT_CLASS_ENTRY、zend_register_internal_classでクラスを定義。 ○ zend_register_list_destructors_exでデストラクタ時の処理を設定できるらしい。 - C++ で PHP Extension を書く方法 † -- http://viz.is-a-geek.com/~viz/cw/index.php?PHP%20Extension - PHP extension からコールバックで hello, world を表示する -- http://ido.nu/kuma/2007/03/02/calling-php-user-defined-function-from-php-extension/ ** 本家 [#sfc9ce08] - ZEND DEVELOPER ZONE (Tag: Extension) -- http://devzone.zend.com/public/view/tag/Extension ** Klab [#ld18065e] - [http://lab.klab.org/modules/mediawiki/index.php/DSAS%E3%83%96%E3%83%AD%E3%82%B0%E3%81%BE%E3%81%A8%E3%82%81#PHP_Extension_.E3.82.92.E4.BD.9C.E3.82.8D.E3.81.86 PHP Extension を作ろう] -- [http://dsas.blog.klab.org/archives/50777398.html 第1回 まずは Hello World] | [http://dsas.blog.klab.org/archives/50782987.html 第2回 引数と返値] | [http://dsas.blog.klab.org/archives/50903613.html 第3回 クラスを作ろう] * 関連 [#o55ed4ff] - SWF Editor for PHP ([[swfed]]) |