- 追加された行はこの色です。
- 削除された行はこの色です。
- PHP/ext へ行く。
TITLE:PHP extension の作り方
swfed extension を作成した時のメモ
#contents
* 準備 [#prepare]
** ディレクトリ作成 [#mkdir]
$ cd php-x.x.x/ext
$ ./ext_skel --extname=swfed
$ cd swfed
** configure 作成 [#configure]
- 必要に応じて後でやり直せる (.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
* クラス実装 [#class]
** 定義 (php_swfed.h) [#define]
- クラスエントリ作成
static zend_class_entry *swfeditor_ce;
- クラスメソッド定義
PHP_METHOD(swfed, __construct);
PHP_METHOD(swfed, input);
** 実装 (swfed.c) [#impl]
- ファンクションエントリ作成
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 に登録したデータの一般的な引き出し方) [#objdata]
- getThis() で取れる class instance へのポインタを zend_read_properties の第二引数に指定して Zend 管理データから引き出す。
zend_hash_find
Z_LVAL_PP
zend_list_find
*** 引数の取り方 (string 型) [#arg_string]
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"s", &str, &str_len)
*** 引数の取り方 (可変長引数1) [#args1]
- 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;
}
*** 引数の取り方 (可変長引数2) [#args2]
- zend_get_parameters_array_ex()
- http://manual.xwd.jp/zend.arguments.html
*** 返り値 [#retvalue]
- 例
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の翻訳]
*** クラス定数の定義 [#classconst]
- PHP_MINIT_FUNCTION にて以下のように設定。
#define REGISTER_SWFED_CLASS_CONST_LONG(const_name, value) \
zend_declare_class_constant_long(swfeditor_ce, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
REGISTER_SWFED_CLASS_CONST_LONG("SHAPE_BITMAP_NONE", SWFED_SHAPE_BITMAP_NONE);
* 警告 [#warning]
- ext/standard/array.c
php_error_docref(NULL TSRMLS_CC, E_WARNING, "step exceeds the specified range");
* 例外 [#exception]
** exception の飛ばし方 [#be20eb71]
zend_throw_exception_ex(zend_exception_get_default(), 1, "Exception at %s:%d",
__FILE__, _LINE__);
- 第一引数は zend_class_entry * なので、Exception の継承クラスを作っておけば、好きな Exception を実装して飛ばせそう。
* 参考 [#ref]
- 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/
- 【PHPext】PHP拡張モジュールの作成
-- http://memo.majide.com/pukiwiki.php?%A1%DAPHPext%A1%DBPHP%B3%C8%C4%A5%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB%A4%CE%BA%EE%C0%AE
- Writing PHP Extensions - PHP Quebec 2009
-- http://www.scribd.com/doc/14125196/Writing-PHP-Extensions-PHP-Quebec-2009
** 本家 [#official]
- ZEND DEVELOPER ZONE (Tag: Extension)
-- http://devzone.zend.com/public/view/tag/Extension
- Extension Writing Part II: Parameters, Arrays, and ZVALsの翻訳です。
-- http://devlog.agektmr.com/wiki/index.php?PHP%2FExtension%20Writing%20Part%20II%20Parameters%2C%20Arrays%2C%20and%20ZVALs
- php-4.3.7 README.EXT_SKEL 日本語訳 @shoma
-- http://catbot.net/doc/ext_skel.html
- Building Custom PHP Extensions
-- http://www.slideshare.net/ioseb/building-custom-php-extensions-15610717
** Klab [#klab]
- [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回 クラスを作ろう]
* その他 [#etc]
- PHP extensions workshop
-- http://www.slideshare.net/jpauli/php-extensionsworkshop
- O'REILLY Programming PHP - 14.8. Returning Values
-- http://docstore.mik.ua/orelly/webprog/php/ch14_08.htm
* 関連 [#rel]
- SWF Editor for PHP ([[swfed]])
- [[PHP/ext/win]]PHP extension の作り方 (Windows 編)