拡張モジュールの作成

まず最初に、非常に単純な拡張モジュールを作成してみましょう。この拡張モジュールは、 パラメータとして受け取った整数値をそのまま返すというだけの関数を実装しています。 ソースを 例46-2 に示します。

例 46-2. 単純な拡張モジュール

/* 標準ヘッダを include します */
#include "php.h"

/* エクスポートする関数を宣言します */
ZEND_FUNCTION(first_module);

/* Zend がこのモジュールの内容を知るための、関数リスト */
zend_function_entry firstmod_functions[] =
{
    ZEND_FE(first_module, NULL)
    {NULL, NULL, NULL}
};

/* モジュールについての情報 */
zend_module_entry firstmod_module_entry =
{
    STANDARD_MODULE_HEADER,
    "First Module",
    firstmod_functions,
    NULL, 
    NULL, 
    NULL, 
    NULL, 
    NULL,
    NO_VERSION_YET,
    STANDARD_MODULE_PROPERTIES
};

/* Zend にこのモジュールについて説明するための、標準「スタブ」ルーチンを実装します */
#if COMPILE_DL_FIRST_MODULE
ZEND_GET_MODULE(firstmod)
#endif

/* PHP で使用するための関数を実装します */
ZEND_FUNCTION(first_module)
{
    long parameter;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &parameter) == FAILURE) {
        return;
    }

    RETURN_LONG(parameter);
}

これは、PHP モジュールとして動作する完全なコードです。 ソースコードについてはあとですぐに説明しますが、 その前にまずビルド方法について説明しておきましょう (API についての議論の前に、とりあえず実際に動かしてみたいという 短気な人たちのためです)。

注意: この例のソースは、PHP 4.1.0 以降に含まれる Zend の新機能を使用しています。 PHP 4.0.x ではコンパイルできません。

モジュールのコンパイル

モジュールをコンパイルするには、基本的に 2 種類の方法があります。

最初の方法のほうが断然お勧めです。PHP 4.0 以降、 この仕組みは標準化され、洗練されたビルド手順に組み込まれています。 あまりに洗練されすぎているという事実は、裏を返せば欠点でもあります。 つまり、最初のうちはなかなか理解できないということです。 この章の後半ではより詳細に説明しますが、 まず最初はデフォルトのファイルを使用して進めていきましょう。

2 番目の方法は、(何らかの理由で) PHP の完全なソースツリーを もっていない、すべてのファイルに対するアクセス権限がない、 あるいは単にキーボードと戯れていたいなどといった人たちにお勧めです。 これらはどれもめったにないケースではありますが、 この文書を完全なものにするためにこちらの方法についても説明しておきます。

Make を使用したコンパイル. サンプルソースを標準的な仕組みでコンパイルするには、 PHP ソースツリーの ext ディレクトリ以下に サンプルのディレクトリをコピーします。 それから buildconf を実行すると、 新しい拡張モジュール用の適切なオプションを含む configure スクリプトが作成されます。 デフォルトでは、すべてのサンプルソースは無効になります。 そのため、この作業でビルド手順が破壊されてしまう恐れはありません。

buildconf を実行すると、configure --help の結果に以下が追加されます。

--enable-array_experiments   BOOK: Enables array experiments
  --enable-call_userland       BOOK: Enables userland module
  --enable-cross_conversion    BOOK: Enables cross-conversion module
  --enable-first_module        BOOK: Enables first module
  --enable-infoprint           BOOK: Enables infoprint module
  --enable-reference_test      BOOK: Enables reference test module
  --enable-resource_test       BOOK: Enables resource test module
  --enable-variable_creation   BOOK: Enables variable-creation module

先ほど 例46-2 で示したモジュールは、 --enable-first_module あるいは --enable-first_module=yes で使用可能になります。

手動でのコンパイル. モジュールを手動でコンパイルするには、以下のコマンドを実行しなければなりません。

作業コマンド
コンパイルcc -fpic -DCOMPILE_DL_FIRST_MODULE=1 -I/usr/local/include -I. -I.. -I../Zend -c -o <your_object_file> <your_c_file>
リンクcc -shared -L/usr/local/lib -rdynamic -o <your_module_file> <your_object_file(s)>

モジュールをコンパイルするためのコマンドでは、コンパイラに対して 位置独立なコードを出力するように指示しています (-fpic は省略できません)。 また、定数 COMPILE_DL_FIRST_MODULE を指定することで、 モジュールのコードを動的ロード可能なモジュールとしてコンパイルするようにしています (上のテストモジュールではこれをチェックしています。これについては後で説明します)。 これらのオプションに続いて、ソースファイルをコンパイルするために必要な 最小限の標準インクルードパスを指定しています。

注意: サンプルのインクルードパスは、すべて ext ディレクトリからの相対パスです。 別の場所でコンパイルする場合は、それに応じてパスを変更してください。 必要なのは、PHP ディレクトリおよび Zend ディレクトリ、そして (必要に応じて) モジュールの存在するディレクトリです。

リンク用のコマンドも、動的モジュールとしてリンクするためのごく平凡なものです。

コンパイル用のコマンドに最適化オプションを含めることもできますが、 この例では省略しています (しかし、いくつかのオプションは 先に説明した makefile のテンプレートに含められています)。

注意: 手動でのコンパイルおよびリンクで PHP に静的モジュールとして組み込む手順は、非常に面倒なものとなります。 そのため、ここでは扱いません (これらのコマンドをすべてタイプするのは効率的ではありません)。