Top > PHP > ext

swfed extension を作成した時のメモ

準備

ディレクトリ作成

$ cd php-x.x.x/ext
$ ./ext_skel --extname=swfed
$ cd swfed

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

クラス実装

定義 (php_swfed.h)

  • クラスエントリ作成
    static zend_class_entry *swfeditor_ce;
  • クラスメソッド定義
    PHP_METHOD(swfed, __construct);
    PHP_METHOD(swfed, input);

実装 (swfed.c)

  • ファンクションエントリ作成
    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 に登録したデータの一般的な引き出し方)

  • getThis() で取れる class instance へのポインタを zend_read_properties の第二引数に指定して Zend 管理データから引き出す。
    zend_hash_find
    Z_LVAL_PP
    zend_list_find

引数の取り方 (string 型)

zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                             "s", &str, &str_len)

引数の取り方 (可変長引数1)

  • 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)

返り値

クラス定数の定義

  • 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);

警告

  • ext/standard/array.c
    php_error_docref(NULL TSRMLS_CC, E_WARNING, "step exceeds the specified range");

例外

exception の飛ばし方

zend_throw_exception_ex(zend_exception_get_default(), 1, "Exception at %s:%d",
                        __FILE__, _LINE__);
  • 第一引数は zend_class_entry * なので、Exception の継承クラスを作っておけば、好きな Exception を実装して飛ばせそう。

参考

本家

Klab

その他

関連


Reload   Diff   Front page List of pages Search Recent changes Backup Referer   Help   RSS of recent changes
Last-modified: Tue, 24 Nov 2015 18:55:04 JST (375d)