|
|
付録 F. PHP 3の拡張
このセクションはPHP3の拡張方法に関するとても古臭いデモです。
PHP4に関心があるのであれば、Zend APIの
セクションを読んでください。PHPソースの種々のファイルも
読むとよいでしょう。
README.SELF-CONTAINED-EXTENSIONSや
README.EXT_SKELです。
全ての関数は次のような形式です。
void php3_foo(INTERNAL_FUNCTION_PARAMETERS) {
} |
関数が引数を取らない場合でも、このような形式でコールされます。
引数は常にpval型です。この型は、実際の引数の型をメンバーとする
unionを有しています。
関数が二つの引数を取る場合、関数の最初に次のような処理を
行なうことになります。
例 F-1. 引数の取得 pval *arg1, *arg2;
if (ARG_COUNT(ht) != 2 || getParameters(ht,2,&arg1,&arg2)==FAILURE) {
WRONG_PARAM_COUNT;
} |
|
注意: 引数は値渡しでも参照渡しでもかまいません。どちらの場合でも
&(pval *) を getParameters に渡す必要があります。
n 番目のパラメータが参照渡しであるかどうかを調べたい場合、
関数 ParameterPassedByReference(ht,n) を使用することができます。
この関数は、1 または 0 を返します。
渡されたパラメータのどれかを変更する場合、
参照渡しであるか、値渡しであるかにかかわらず、
pval_destructor をコールすることにより初期化するか、
ARRAYにパラメータを加えたい場合には、
返り値を ARRAYとして処理する internal_functions.h
の中の関数に類似の関数を使用することが可能です。
また、パラメータを IS_STRING に変更する場合、
estrdup() された文字列と文字列の長さを最初に割り付けた後で始めて
型を IS_STRING に変更することが可能であることに注意して下さい。
すでに IS_STRING または IS_ARRAY であるパラメータの文字列を
変更する場合、最初に pval_destructor を実行する必要があります。
関数は、可変の数の引数をとることができます。
ある関数が 2 つまたは 3 つの引数のどちらかをとる場合、
次のようにしてください。
例 F-2. 可変引数 pval *arg1, *arg2, *arg3;
int arg_count = ARG_COUNT(ht);
if (arg_count < 2 || arg_count > 3 ||
getParameters(ht,arg_count,&arg1,&arg2,&arg3)==FAILURE) {
WRONG_PARAM_COUNT;
} |
|
各引数の型は pval 型フィールドに保存されます。
この型は、次のどれかとすることができます。
表 F-1. PHP 内部の型 IS_STRING | 文字列 | IS_DOUBLE | 倍精度浮動小数点 | IS_LONG | 倍精度整数 | IS_ARRAY | 配列 | IS_EMPTY | 空 | IS_USER_FUNCTION | ?? | IS_INTERNAL_FUNCTION | ?? (このうちのいくつかは関数に渡すことができません。 - 削除) | IS_CLASS | ?? | IS_OBJECT | ?? |
ある型の引数を得たが、他の型で使用したい場合、または、
その引数を強制的にある型で使用したい場合、
次の変換関数のどれかを使用することができます。
convert_to_long(arg1);
convert_to_double(arg1);
convert_to_string(arg1);
convert_to_boolean_long(arg1); /* 文字列が "" または "0" の場合 0、その他の場合 1 になります */
convert_string_to_number(arg1); /* 文字列に応じて値を LONG または DOUBLE に変更します */ |
これらの関数は、全てその場で変換されます。
値は全く返されません。
実引数は、結合体に保持されます。
メンバーは、次のようになります。
IS_STRING: arg1->value.str.val
IS_LONG: arg1->value.lval
IS_DOUBLE: arg1->value.dval
関数により必要とされる全てのメモリーは、
emalloc() または estrdup() のどちらかにより
確保される必要があります。これらの関数は、
通常の malloc() および strdup() 関数に似た
メモリー関連処理を行う抽象関数です。
メモリーは、efree() により開放される必要があります。
このプログラムには、2種類のメモリーがあります。
つまり、パーサーに変数として返されるメモリーと
内部関数での一次的な記憶領域用に必要なメモリーです。
文字列をある変数に代入しパーサーに返したい場合、
まず emalloc() または estrdup() のどちらかにより
メモリーを確保する必要があります。
このメモリーは、同じ関数において元の代入値を上書きしない限り
開放することはできません。
(この種のプログラミング法は、推奨されません。)
自分の関数・ライブラリで必要な一時的・永続的メモリを確保するためには、
emalloc()、estrdup()、efree() 関数を使用する必要があります。
これらの関数は、それぞれが対応する関数 (malloc,strdup,free)
と全く同じ動作をします。
emalloc() または estrdup() を実行した場合、
ただし、プログラム実行終了時まで確保しつづけるつもりである場合を除き、
どこかで efree() を行う必要があります。
さもなくば、メモリーリークを起こす可能性があります。
関数が対応するそれぞれが関数と全く同じ動作をするという意味は
次のようなものです。
つまり、emalloc() も estrdup() もされていないメモリーについて efree()
を行った場合、セグメンテーションフォルトを発生する可能性があります。
このため、消費したメモリーを解放する際には注意して下さい。
"-DDEBUG" でコンパイルした場合、PHP 3は、指定したスクリプトの実行が
終了した際に、emalloc() および estrdup()
で確保したが efree() でまだ開放されていない全メモリーのリストを
表示します。
シンボルテーブルに変数を設定することを容易にするために
以下のようなマクロが用意されています。
SET_VAR_STRING(name,value) SET_VAR_DOUBLE(name,value) SET_VAR_LONG(name,value)
警告 |
SET_VAR_STRINGを使用する場合は注意が必要です。
value は、メモリ管理コードが後にこのポインタについて free を
行おうとするため、手動で malloc を行う必要があります。
静的に確保されたメモリーを SET_VAR_STRING に渡してはなりません。
|
PHPのシンボルテーブルは、ハッシュテーブルとして実装されています。
いつなんどきでも &symbol_table は 'main' シンボルテーブルへの
ポインターであり、active_symbol_table は現在アクティブな
シンボルテーブルを指しています。(この二つは実行開始時には同じですが、
関数の中にいる時には異なっています。)
次の例は 'active_symbol_table' を使用します。
'main' シンボルテーブルを使用したい場合には、
これを &symbol_table で置きかえる必要があります。
また、以下に説明するように同じ関数を配列にも適用することができます。
例 F-3. $foo がシンボルテーブルに存在するかどうかを調べる if (hash_exists(active_symbol_table,"foo",sizeof("foo"))) { exists... }
else { doesn't exist } |
|
例 F-4. シンボルテーブルにある変数のサイズの調べ方 hash_find(active_symbol_table,"foo",sizeof("foo"),&pvalue);
check(pvalue.type); |
|
PHPにおける配列は、シンボルテーブルと同じくハッシュテーブル
により実装されています。
このため、上記の二つの関数は配列の内部で変数を確認するためにも
使用可能です。
シンボルテーブルに配列を新規に定義したい場合、
次のようにする必要があります。
まず、hash_exists() または hash_find() を用いて
その配列の存在や、適切に開放されているかどうかを
確認する方が良いでしょう。
次に、その配列を次のように初期化します。
例 F-5. 新規の配列の初期化 pval arr;
if (array_init(&arr) == FAILURE) { failed... };
hash_update(active_symbol_table,"foo",sizeof("foo"),&arr,sizeof(pval),NULL); |
|
このコードは、アクティブシンボルテーブルにおいて新規配列を宣言しています。
この配列は空です。
以下に新しいエントリをこの配列に加える例を示します。
例 F-6. 新規配列にエントリを加える pval entry;
entry.type = IS_LONG;
entry.value.lval = 5;
/* $foo["bar"] = 5 を定義する */
hash_update(arr.value.ht,"bar",sizeof("bar"),&entry,sizeof(pval),NULL);
/* $foo[7] = 5 を定義する */
hash_index_update(arr.value.ht,7,&entry,sizeof(pval),NULL);
/* $foo[] における次の空きメモリー、つまり $foo[8] を 5 に定義する
* (php2 と同様に動作します)
*/
hash_next_index_insert(arr.value.ht,&entry,sizeof(pval),NULL); |
|
ハッシュに挿入された値を修正したい場合、
まずハッシュから値を取り出す必要があります。
オーバーヘッドを避けるため、 pval ** を
ハッシュ付加関数に与え、
ハッシュの内部に挿入された要素のアドレスを示す
pval * を用いて更新を行うことができます。
(上記の全ての例のように)この値が、 NULL の場合、このパラメータは
無視されます。
hash_next_index_insert() は、PHP 2.0 の "$foo[] = bar;"
とほぼ同じロジックを用いています。
関数から配列を返す構成とする場合、
以下のようにするだけで配列の初期化を行うことができます。
if (array_init(return_value) == FAILURE) { failed...; } |
続いて、ヘルパー関数を用いて値を付加します。
add_next_index_long(return_value,long_value);
add_next_index_double(return_value,double_value);
add_next_index_string(return_value,estrdup(string_value)); |
もちろん、付加が配列の初期化直後に行われない場合には、
配列をまず確認する必要があることでしょう。
pval *arr;
if (hash_find(active_symbol_table,"foo",sizeof("foo"),(void **)&arr)==FAILURE) { can't find... }
else { use arr->value.ht... } |
hash_find は pval ポインタへのポインタを受け取り、
pval ポインタではないことに注意して下さい。
ほとんど全てのハッシュ関数は、SUCCESSまたはFAILUREを返します。
(ただし、論理値を返す hash_exists() を除きます。)
関数からの返り値を作成することを容易にするための
複数のマクロが利用可能です。
RETURN_* マクロは、全て返り値をセットし関数から戻ります。
RETURN
RETURN_FALSE
RETURN_TRUE
RETURN_LONG(l)
RETURN_STRING(s,dup) dupがTRUEの場合、文字列をコピーします。
RETURN_STRINGL(s,l,dup) 指定された長さ(l)の文字列(s)を返します。
RETURN_DOUBLE(d)
RETVAL_* マクロは返り値をセットしますが、関数から戻りません。
RETVAL_FALSE RETVAL_TRUE RETVAL_LONG(l) RETVAL_STRING(s,dup) dup が TRUE の場合、文字列をコピーします。 RETVAL_STRINGL(s,l,dup) 指定された長さ (l) の文字列 (s) を返します。 RETVAL_DOUBLE(d)
上記の文字列マクロは、全て 's' 引数に estrdup() を行います。
このため、マクロをコールした後、引数を安全に開放することができます。
他の選択肢としては、静的に確保されたメモリを使用することもできます。
関数が論理値として成功/エラーの応答を返す場合、
それぞれ RETURN_TRUE および RETURN_FALSE を使用するようにして下さい。
関数はオブジェクトや配列といった複雑なデータ型を返すことも可能です。
オブジェクトを返すには、次のようにします。
object_init(return_value) をコールします。 オブジェクトを値で埋めます。この際に用いる関数の一覧を
以下に示します。 可能ならば、このオブジェクト用の関数を登録します。
オブジェクトから値を得るために、関数は、active_symbol_table から
"this" を取得する必要があります。 "this" の型は、IS_OBJECT である必要が
あります。これは、基本的に通常のハッシュテーブルです。
(すなわち、.value.ht に通常のハッシュ関数が使用可能です)
実際の関数の登録は、次のようにして実行できます。
add_method( return_value, function_name, function_ptr ); |
オブジェクトを操作するための関数を以下に示します。
add_property_long( return_value,
property_name, l ) - long 型で '1' という値を有する 'property_name' という名前のプロパティを追加します add_property_double( return_value,
property_name, d ) - 同じですが、倍精度実数を加えるところが違います。 add_property_string( return_value,
property_name, str ) - 同じですが、文字列を加えるところが違います。 add_property_stringl( return_value,
property_name, str, l ) - 同じですが、長さ 'l' の文字列を加えるところが違います。
配列を返すには次のようにします。
array_init(return_value) をコールします。 配列を値で埋めます。この用途に用いる関数の一覧を以下に示します。
配列を用いるための関数は次のようなものです。
add_assoc_long(return_value,key,l) -
キー が 'key' のエントリと long 値 'l' を加えます。 add_assoc_double(return_value,key,d) add_assoc_string(return_value,key,str,duplicate) add_assoc_stringl(return_value,key,str,length,duplicate)
文字列の長さを指定します。 add_index_long(return_value,index,l) -
索引が 'index' となるエントリに long 値 'l' を加えます。 add_index_double(return_value,index,d) add_index_string(return_value,index,str) add_index_stringl(return_value,index,str,length)
- 文字列長さを指定します。 add_next_index_long(return_value,l) -
次にアクセスされる配列エントリと long 値 'l' を加えます。 add_next_index_double(return_value,d) add_next_index_string(return_value,str) add_next_index_stringl(return_value,str,length)
- 文字列長さを指定します。
PHP は様々な型のリソースを処理する標準的な手段を有しています。
この手段は、PHP 2.0 のリンク付リストを完全に置きかえるものです。
利用可能な関数:
php3_list_insert(ptr, type) - 新規に挿入されたリソースの
'id' を返します。
php3_list_delete(id) - id で指定されたリソースを削除します。
php3_list_find(id,*type) - 指定した id が指すリソースへのポインタを
返し、type にそのリソースの型を代入します。
通常、これらの関数は SQL ドライバー用に使用されますが、
ファイル記述子の管理等の他の目的に
使用することも可能です。
典型的なコードは、次のようになります。
例 F-7. 新規リソースの追加 RESOURCE *resource;
/* ...リソース用のメモリを確保し、リソースを獲得します... */
/* 新規のリソースをリストに追加します */
return_value->value.lval = php3_list_insert((void *) resource, LE_RESOURCE_TYPE);
return_value->type = IS_LONG; |
|
例 F-8. 既存のリソースの使用法 pval *resource_id;
RESOURCE *resource;
int type;
convert_to_long(resource_id);
resource = php3_list_find(resource_id->value.lval, &type);
if (type != LE_RESOURCE_TYPE) {
php3_error(E_WARNING,"resource index %d has the wrong type",resource_id->value.lval);
RETURN_FALSE;
}
/* ...リソースを使用します... */ |
|
例 F-9. 既存のリソースの削除 pval *resource_id;
RESOURCE *resource;
int type;
convert_to_long(resource_id);
php3_list_delete(resource_id->value.lval); |
|
リソース型は php3_list.h の enum list_entry_type にて登録する必要が
あります。加えて、全ての新規リソース型の定義の際、
list.c の list_entry_destructor() の中に shutdown 用のコードを
加える必要があります。(shutdown の中で何もする必要がない場合でも、
空のコードを加える必要があります。)
PHP は、持続的リソース(すなわち、アクセス間は保持されるリソース)
を保存する標準的な手段を有しています。
この機能を用いた最初のモジュールは、MySQL モジュールであり、
mSQL が後に続きました。
このため、mysql.c を読むことにより持続的リソースの必要性に関する
一般的な感覚を得ることができます。
見る必要がある関数は次のようなものです。
php3_mysql_do_connect | php3_mysql_connect() | php3_mysql_pconnect() |
持続的モジュールの一般的な考えは次のようなものです。
セクション (9) に記載された標準リソースリストと共に
動作するモジュール全体をコーディングします。
そのリソースが持続的リソースリストに既に存在するかどうかを
確認する特別な接続関数をコーディングします。
この作業が完了している場合、標準のリソースリストに
持続的リソースリストへのポインタとしてこの関数を登録します。
(1.項により、残りのコードは直ちに動作するはずです。)
完了していない場合、これを作成した後、持続的リソースリストに加え、
標準リソースリストにこの関数を指すポインタを加えます。
この場合、このポインタが標準リソースリストにあるため、
コード全体が動作します。
次回接続した際には、そのリソースが持続的リソースリスト
にあるため、再度作成されることなく使用されます。
これらのリソースは、別の型として登録する必要があります。
(例えば、非持続的リンク用に LE_MYSQL_LINK、
持続的リンク用に LE_MYSQL_PLINK)
mysql.c を読むと、より複雑な接続関数を除いてはモジュールの他の部分を
変更する必要がないということが分かるでしょう。
'list' が 'plist' に置きかえられるだけで、
全く同じインターフェースが、標準リソースリストと
持続的リソースリストに存在します。
php3_plist_insert(ptr, type) - 新規に挿入されたリソースの 'id'
を返します。
php3_plist_delete(id) - 指定された id のリソースを削除します。
php3_plist_find(id,*type) - 指定された id のリソースへのポインタを返し、
'type' をそのリソースの型で更新します。
しかし、持続的モジュールを実装しようとする際に
これらの関数が役に立たないことがわかる場合もありえます。
通常の場合、持続的リソースリストがハッシュテーブルそのものである
という事実が利用されます。
例えば、MySQL/mSQL モジュールにおいて、pconnect() コール(持続的接続)
があった場合、その関数は、関数に渡されるホスト・ユーザー・パスワード
から文字列を作成します。そして、この文字列をキーとして
SQL リンクをハッシュに加えます。
次に誰かが pconnect() を同じホスト・ユーザー・パスワードでコール
した場合、同じキーが生成されます。
この場合、この関数は持続的リンクのリストにある SQL リンクを見つけます。
より詳細な記述が行われるようになるまで、
plist のハッシュテーブル機能の使用法を知るためには、
mysql.c または msql.c を見る必要があります。
注意すべき重要な点:持続的リソースリストに加えられるリソースは、
PHP のメモリーマネージャで確保されたものであってはなりません。
すなわち、emalloc(),estrdup()等で生成されたものであってはなりません。
むしろ、通常の malloc(),strdup() 等を使用するべきです。
その理由は単純です。リクエストの終了時(ヒットの終了時)に
PHP のメモリーマネージャを使用して確保された全てのメモリー領域は、
削除されるからです。
持続的リストは、リクエストの終了時に消去されるようにはなっていないので、
このようなリソース確保するために
PHPのメモリーマネージャを使用するべきではありません。
持続的リストに加えようとするリソースを登録する際に、
非持続的リストと持続的リストの両方にデストラクタを
加える必要があります。
非持続的リストのデストラクタは、何もする必要がありません。
持続的リストのデストラクタは、この型により得られた全ての
リソース(例えば、メモリー、SQLリンク、等)を開放する必要が
あります。
非持続的リソースと全く同様に、全てのリソースについてデストラクタ
を備える必要があります。
破棄を要する必要がない場合には、デストラクタは空とすることができます。
emalloc() とその派生したものは、持続的リストに関連して
使用するべきではなく、このような場合、efree() も使うべきではないという
ことを覚えておいてください。
PHPの機能の多くは、実行時に設定を行うことが可能です。
これらの設定用命令は、php3.ini ファイルまたは、Apache モジュール版の
場合、Apache .conf ファイルに書かれています。
この Apache .conf ファイルの中にこれらを記載することの利点は、
ディレクトリ毎に設定が可能なことです。
これは、例えばあるディレクトリはある safemodeexecdir を
有しているとき、他のディレクトリは、別のものを指定することが
できることを意味します。
この設定のきめの細かさは、サーバーが複数の仮想ホストを
サポートする場合に特に便利です。
新しい命令を加えるために必要な手順は次のようなものです。
mod_php3.h にある php3_ini_structureに命令を加えます。
main.c の php3_module_startup 関数を編集し、適当なcfg_get_string()
またはcfg_get_long()コールを加えます。
mod_php3.c の php3_commands 構造体に命令、制約、コメントを
加えます。制約の部分を記録しておいて下さい。
RSRC_CONFは、Apache .conf ファイルにのみある命令です。
OR_OPTIONS命令は、通常の .htaccessファイルを含むあらゆる
場所に置くことができます。
php3take1handler()またはphp3flaghandler()はどちらも命令に
関する適当なエントリを追加します。
functions/info.c 中の _php3_info() 関数の
設定セクションに、新しい命令を追加する必要があります。
最後に、もちろん、新しい命令をどこかで使う必要があります。
この命令は、php3_ini.命令 としてアクセスできます。
sylbert at geodesiconline dot com
21-Jun-2002 01:18
Just found out that functions in php need to neccessarily be in lower case! However, using a function like testMe doesn't throw any errors during compile time .. its just shows up as an undeclared function when called from a script. Instead use something like test_me & it works just fine.
akimov at e-mail dot ru
26-Apr-2001 05:19
I recomended visit Zend API Documentation pages
[editor note: These docs also live in the PHP manual
Use those docs to Extend PHP 4]
ale at tana dot it
14-Mar-2001 09:48
PORTING CUSTOM C FUNCTION FROM PHP3 TO PHP4
And I mean just functions, not full-fledged php extension. I had a couple
of them, working with PHP3, and I have ported them in PHP4. Here's how.
1) Makefile
you should have CFLAGS something like
-I/path/to/php/php-4.0.4pl1/Zend
-I/path/to/php/php-4.0.4pl1
-I/path/to/php/php-4.0.4pl1/TSRM
-I/path/to/php/php-4.0.4pl1/main
-fPIC
-DCOMPILE_DL=1
Only the include paths changed from PHP3.
2) Interface with PHP
the php3_module_entry is now called zend_module_entry and has
the same structure. The get-module function from which you used to
return that value is not DLEXPORT, but ZEND_DLEXPORT. You
may want to use the ZEND_GET_MODULE macro.
For the function_entry, you may want to use the PHP_FE macros,
but I found the PHP_NAMED_FUNCTION implied less changes.
It goes as
PHP_NAMED_FUNCTION(arrayret); /* declaration */
and
/* in php3 was
DLEXPORT void arrayret(INTERNAL_FUNCTION_PARAMETERS) */
PHP_NAMED_FUNCTION(arrayret) /* definition */
{
pval **arg;
char buf[512];
int ok = 0, i = -1;
if (ZEND_NUM_ARGS() != 1 ||
zend_get_parameters_ex(1, &arg) != SUCCESS ||
(*arg)->type != IS_STRING ||
(*arg)->value.str.val == NULL)
{
WRONG_PARAM_COUNT;
}
...
You've seen that *arg becomes **arg. The ..._ex() function will take
the address of a pointer to pointer. ZEND_NUM_ARGS doesn't take
any parameter (used to be ht).
3) Includes
#include <php.h>
#include <zend_globals.h>
4) Insert indirection
One difficult point is the extra level of indirection that was introduced
for reference counting. If you don't use complex data types your C
function should now work. If you use, e.g., arrays, keep that level
of indirection in mind: don't store a pval into an array, store a pointer.
I had things as
if (array_init(return_value) == SUCCESS)
{
ok = 1;
for (i = 0; i < 100 && ok; ++i) /* insert 100 arrays in return value */
{
pval entry;
char buf[80];
if ((ok = array_init(&entry) == SUCCESS) != 0)
{
static char const entry_1[] = "one";
static char const entry_2[] = "two";
pval e1, e2;
e1.value.str.val = e2.value.str.val = NULL;
e1.type = e2.type = IS_STRING;
e1.value.str.len = sprintf(buf, "%3d/%010u", i, i);
e1.value.str.val = estrndup(buf, e1.value.str.len);
ok = e1.value.str.val != NULL &&
_php3_hash_update(entry.value.ht, (char*)entry_1,
sizeof entry_1, &e1, sizeof e1, NULL) == SUCCESS;
if (ok) /* continue assigning a second string, etc... */
...
This stuff compiles due to some compatibilty macro definitions, but
it doesn't work. The quickest way around is to insert an intermediate
function. To make the code above work in PHP4 i preceded it with
the following:
#undef _php3_hash_update
#define _php3_hash_update php4_hash_update_patch
static int php4_hash_update_patch(HashTable *ht,
char *arKey, uint nKeyLength,
void *pData, uint nDataSize, void **pDest)
{
zval *tmp;
int rtc;
if (nDataSize != sizeof(zval)) /* check it was a pval */
return FAILURE;
ALLOC_ZVAL(tmp); /* you need zend_globals.h for this */
*tmp = *(zval*)pData;
tmp->is_ref = 0;
tmp->refcount = 1;
if ((rtc = zend_hash_update(ht,
arKey, nKeyLength,
(void*)&tmp, sizeof(zval*), pDest)) == FAILURE)
{
FREE_ZVAL(tmp);
}
return rtc;
}
Similar patches can be done for _php3_hash_next_index_insert,
etcetera. You got the idea.
I hope this may save some time to an occasional code porter,
keep in mind I'm not a zend (sic) guru, I just crashed my head
quite hardly before realizing what was going wrong.
And
5) good luck!
befletch at yahoo dot com
30-Sep-1999 12:33
Something about the PHP build process is needed here; perhaps an example showing how to make your own "Hello, World" extension. Since that doesn't exist yet...
<p>
If you want to create an extension, you will need reasonably current versions of the tools m4, autoconf, libtool, and (I think) automake. All of these are available at
<p>
Once these are installed, go into the 'ext' directory of your php install and run the 'ext_skel' script to create your extension directory with some skeleton contents. You will need to edit at least the config.m4 file, and of course add your own code. Other extensions are useful models, and the GNU documentation for autoconf is useful for understanding macros used in config.m4.
<p>
The final step required to insert your code into the PHP build process is to go to the php root directory and run the 'buildconf' script. You should now find references to your extension in the 'configure' script, and if you designed your config.m4 to make your extension conditional, 'configure' should have command-line switches for you.
<p>
After running 'configure', your extension should now be part of PHP's build process. (You may want to verify that php_config.h has properly set any 'HAVE_<your-extension-here>' macros properly defined.) If this all goes well, you should be ready to concentrate on the C code for your extension.
| |