C 言語は、非常に低レベルなレイヤーを今風に扱えるようにした言語です。 PHP のように組み込みでさまざまな機能が用意されているわけではありません。 リフレクションや動的モジュール読み込み、範囲チェック、 スレッドセーフなデータ管理、さまざまなデータ構造 (リンクリストやハッシュテーブルなど) は組み込みの機能としては用意されていません。 と同時に、C 言語はプログラミング言語としての一般的な機能はすべて兼ね備えています。 それなりに努力しさえすれば、先ほどあげた内容はすべて実現可能です。 実際、Zend Engine ではこれらをすべて利用することができます。
Zend API を、拡張しやすくかつわかりやすいものにするためにさまざまな努力を重ねてきました。 しかし、C 言語はどんな拡張に対しても何らかの宣言が必要となるものであり、 不慣れな人が見ると冗長に感じたり説明不足に感じたりすることは避けられません。 これから説明していくこれらの言語構造は、Zend Engine 2 や 3 においては "一度書いたらあとは忘れてしまってよい" ものです。 ここで示すのは、PHP 5.3 の ext_skel で生成したファイル php_counter.h および counter.c の抜粋です。どのような宣言が生成されるのかをごらんください。
注意: 勘のいい方ならお気づきでしょうが、 実際のファイルにはここであげた以外にもいくつかの宣言があります。 これらの宣言は Zend サブシステム群に固有のものであり、 ここで説明するのは適切ではありません。
extern zend_module_entry counter_module_entry; #define phpext_counter_ptr &counter_module_entry #ifdef PHP_WIN32 # define PHP_COUNTER_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 # define PHP_COUNTER_API __attribute__ ((visibility("default"))) #else # define PHP_COUNTER_API #endif #ifdef ZTS #include "TSRM.h" #endif
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_counter.h" /* ... */ #ifdef COMPILE_DL_COUNTER ZEND_GET_MODULE(counter) #endif
注意: counter モジュールを静的にビルドしようとして main/php_config.h を調べた人の中には HAVE_COUNTER という定数が定義されていることにお気づきのかたもおられるかもしれません。 この定数はソースコードのどこでも用いられていません。 理由は簡単で、このチェックは行われないからです。 このチェックは不要なのです。 拡張モジュールが有効になっていなければ、 そのファイルがコンパイル対象となることはないからです。