C++でPHPを拡張する

4144 ワード

前端の时间は1つのReplのPHP Extensionを书いたことがあって、当时の国内の中国语のウェブサイトの上で覚えていて、関连する资料は本当に少なくて、今日レンガを投げて玉を引いていくつか书いて、后者に役に立つことを望んで、あれらの基本的なものは私は赘述しないで、主に话して、PHP ExitensionとPHPの间のパラメータの伝达の问题;
まず私が書いたPHP Extensionについてお話しします.Repl(Yahooのデータ同期のためのツール)はC++APIを提供しているので、私の実現方法は、既存のAPIをC++で包装して、拡張使用に適して、C++のダイナミックライブラリを生成することです.SOは、その後、PHP Extensionにおいて、PHPからのパラメータを簡単に取得する、前述の動的ライブラリが提供するAPIを呼び出すが、問題は、PHPとPHP Extensionとの間のパラメータ伝達方法である.
(ダイナミックライブラリを生成するには、g++-fpic-sharedを使用してコンパイルすればよい.)
1,PHPから渡されたパラメータの数を取得する
この問題は、zend APIがマクロZEND_を定義している.NUM_ARGS(),
                if(ZEND_NUM_ARGS() != 2) WRONG_PARAM_COUNT;
         WRONG_PARAM_COUNTもマクロです.主にデフォルトのエラー情報を投げ出し、呼び出し者に戻る責任を負う.
zend_でAPI.hの定義は以下の通りで,直感的である.
                 ZEND_API void wrong_param_count(void);
                 #define WRONG_PARAM_COUNT { wrong_param_count(); return; }
2,取得パラメータ
これはzend APIの関数を使用します.
               int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, …);
         int num_args:受け入れるパラメータの数;常にTSRMLSの後を追うべきですDC;
         char * type_spec:printfと同様のフォーマット制御文字で、受け入れるパラメータのタイプを示します.
パラメータを取得する変数のポインタに続いています.
制御文字の主なタイプは次のとおりです.
            
  • l-ロング整形
  • d-デュアル精度浮動小数点タイプ
  • s-文字列(空のバイトも可能)とその長さ
  • b-ブール型
  • r-リソース、zval*
  • に保存
  • a-配列、zval*
  • に保存
  • o-(任意のクラスの)オブジェクト、zval*
  • に保存
  • O-(class entryで指定されたクラスの)オブジェクト.zval*
  • に保存されます.
  • z-実際のzval*
  • 次のいくつかの文字は、タイプ説明文字列(そのchar*type_spec)において特別な意味を有します.
  • |-後のパラメータがオプションであることを示します.ユーザーがこれらのパラメータ値を入力しない場合、これらの値はデフォルト値に初期化されます.
  • /-前のパラメータがパラメータ解析関数によって適用されることを示すSEPARATE_ZVAL_IF_NOT_REF()方式は、これらのパラメータが参照でない限り、このパラメータのコピーを提供する.
  • ! - 前のパラメータがNULL(a,o,O,r,zのみ)に設定できることを示します.NULL値が入力された場合、パラメータを格納する変数はNULLに設定されます.
  • 例を見てみましょう./*は長さ、文字列、およびその長さを取得し、zval値を取得します.*/long l;char *s;int s_len;zval *param;if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,                          "lsz", &l, &s, &s_len, ¶m) == FAILURE) {    return;}

  • 私の拡張ではzend_を使いましたget_parameters_ex()は、取り戻されたすべてのパラメータをzval**(後述)の構造に配置します.                  zval ** z_array;                  if(FAILURE = zend_get_parameters_ex(1, &z_array){                          RETURN_BOOL(0);}それから、あなたはとても関数を制御してパラメータに対して解析して制御することができます;これも私がどうしてこれを選んだ原因の1つです:)3、核心の核心、zval; 
    まずzvalの定義を見てみましょう:typedef pval zval;
           typedef struct _zval_struct zval;
           typedef union _zvalue_value {
           long lval; /* long value */
           double dval; /* double value */
           struct {
            char *val;
            int len;
           } str;
           HashTable *ht; /* hash table value */
           struct {
            zend_class_entry *ce;
            HashTable *properties;
          } obj;
          } zvalue_value;
         struct _zval_struct {
        /* Variable information */
        zvalue_value value; /* value */
        unsigned char type; /* active type */
        unsigned char is_ref;
        short refcount;
    };

    zvalのvalueは連合体であり、明らかに様々なタイプの値を収容するために使用され、対応するtypeが値のタイプを示す.is_refとrefcountは、参照と、参照カウントであるかどうかを示すために使用されます.
    ここで、パラメータの「値」を取りました.今の問題はC++の値にすることです(タイプがあります).私が書いた配列解析コード:
        std::map photo;    convert_to_array_ex(z_array);    count = zend_hash_num_elements(Z_ARRVAL_PP(z_array));    zend_hash_internal_pointer_reset(Z_ARRVAL_PP(z_array));    for (i = 0; i < count; i++)    {        char* key;        unsigned long idx;        if (zend_hash_get_current_key(Z_ARRVAL_PP(z_array), &key, &idx, 0) == HASH_KEY_IS_STRING)        {            zend_hash_get_current_data(Z_ARRVAL_PP(z_array), (void**) &z_item);            convert_to_string_ex(z_item);            photo.insert(pair(string(key), string(Z_STRVAL_PP(z_item))));        }        zend_hash_move_forward(Z_ARRVAL_PP(z_array));    }
    今日はこれだけ書きますから、また時間があれば、補充します.
    詳細については、yAnbiNのPHPコアの深さを参照してください.
    広告をして、ほほほ、私达の牛Xの戦友Ranixの翻訳のProgramming PHPのExtending PHPの1章を参照することができます
    //By:恵新宸(xinchen.hui(at)alibaba-inc.com)転載出典を明記してください.