実例で学ぶPHP拡張モジュールの作り方

第2回 Hello, PHP Extension!

この記事を読むのに必要な時間:およそ 8 分

ソースコードを生成する

specファイルの用意ができたら,次はpecl-genコマンドでソースコードやその他のファイルを生成します。pecl-genコマンドの基本的な使い方は,引数としてspecファイルのパスを与えるだけです。

操作1 pecl-genを実行

$ pecl-gen helloworld.xml
Creating 'helloworld' extension in './helloworld'

Your extension has been created in directory ./helloworld.
See ./helloworld/README and/or ./helloworld/INSTALL for further instructions.

さらに続けてlsコマンドで生成されたファイルを確認してみると,操作2のようになりました。これを分類すると図1のようになります。specファイルの内容によっては生成されるファイルの構成が操作2と異なる場合もあります。

操作2 pecl-genで生成されたファイル一覧

$ ls helloworld
CREDITS          config.m4        helloworld.dsp   package.xml      tests
LICENSE          config.w32       helloworld.xml   package2.xml
README           helloworld.c     manual           php_helloworld.h

図1 pecl-genで生成されたファイルの分類

図1 pecl-genで生成されたファイルの分類

マニュアルやpackage.xmlまで生成されているのが興味深いですね。ただしマニュアルといっても,そのままWebブラウザで見られるHTML形式のものではなく,マニュアルの元となるファイル群です。これをコンパイルしてHTML,CHM,PDFなどの形式のマニュアルを生成します。今回はマニュアル生成までは行いませんが,この連載中にはマニュアルやPEARパッケージを制作する回を設ける予定です。

ビルド,テスト,インストール

さてpecl-genの次はモジュールをビルドします。ここから先の作業は最初にphpizeコマンドでconfig.m4からconfigureスクリプトやMakefile.inなどを生成し,configure,make,make installというように,一般に配布されているPHP拡張モジュールのインストール方法とまったく同じです。

標準以外のパスにインストールされているPHPに対して拡張モジュールをビルドしたい場合は,phpizeをフルパスで指定し,configureの引数に --with-php-config=/path/to/php-config を追加します。php-configコマンドはphpizeコマンドと同じディレクトリにインストールされているPHPのビルド情報を取得するためのスクリプトです。

操作3 helloworldモジュールをビルド

$ cd helloworld
$ phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
$ ./configure --enable-helloworld
(省略)
$ make
(省略)
Build complete.
Don't forget to run 'make test'.

無事ビルドできたら,さっそくインストール,と行きたいところですが,その前にちゃんとhelloworld()関数が動作するかテストします。

このときphp.iniのextension_dirディレクティブの値が⁠modules/⁠(カレントディレクトリにあるmodulesディレクトリ)で上書きされるので,php.iniのextensionディレクティブで拡張モジュールを読み込むようにしていると,モジュールが読み込めなかった旨のエラーが出力されてテストが失敗します。make testの際にはphp.iniのextensionディレクティブをすべてコメントアウトしておいてください。

操作4 テストを実行

$ make test
(省略)
=====================================================================
Running selected tests.
PASS helloworld() function [tests/helloworld.phpt] 
=====================================================================
Number of tests :    1                 1
Tests skipped   :    0 (  0.0%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :    0 (  0.0%) (  0.0%)
Tests passed    :    1 (100.0%) (100.0%)
---------------------------------------------------------------------
Time taken      :    0 seconds
=====================================================================

テストが成功したら,いよいよインストールです。

操作5 インストール

$ sudo make install
Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20060613/

Hello, World!

インストールできたら,あとはphp.iniにhelloworldモジュールを読み込むディレクティブ⁠extension=helloworld.so⁠を追加し,WebサーバやFastCGIプロセスを再起動すれば,helloworld()関数が利用できるようになります。

今回はphp.iniの編集やWebサーバ再起動を行わずにコマンドラインでhelloworld()関数を使ってみます。

操作6 Hello, World!

$ php -d extension=helloworld.so -r 'helloworld();'
Hello, World!

make testで確認済みとはいえ,実際に見てみると感慨深いですね※3)⁠

おわりに

これで基本的なspecファイルの書き方と,拡張モジュールのインストール方法が理解していただけたと思います。

実は<extension>タグの子要素はすべて省略しても構わないのですが,今回は解説のため詳しく書きました。specファイルの内容はソースコードだけでなく,自動生成されるマニュアルなどにも反映されるので,モジュールを公開する予定があるなら,なるべく詳しく書くことをお勧めします。逆に自分専用のモジュールを作る場合は<description>タグやリリース情報は一切書かず,本体の開発に専念するのもありでしょう。

本連載で紹介するspecファイルもできる限り詳しい記述をするように務めますが,ページの都合で記事中では省略することがあります。specファイルおよびソースコード一式は本サイトからダウンロードできるようにしますので,そちらと合わせて読んでいただければと思います。

次回はOpenCVライブラリを使ってWEBカメラの画像をキャプチャする拡張モジュールを制作し,外部ライブラリとリンクする方法,引数を取り値を返す関数の作り方などを紹介します。

サンプルファイルのダウンロード

helloworld.xml.txt(specファイル)

次のページは今回使ったCodeGen_PECLタグやZend APIの一覧表です。

※3

すみません,ひとつ嘘をつきました。筆者は何度となくこの作業をしたので,⁠Hello, World!⁠が表示できたぐらいでは感動できませんでした。初めてのときは嬉しかったような気はするのですが,記憶があやふやです。みなさんはいかがでしたしょうか?

ちなみに次回に制作する関数の実行結果が確認ができたときは本当に感動しました。

著者プロフィール

関山隆介(せきやまりゅうすけ)

ジンガジャパン株式会社に所属。PHP拡張モジュールを作った数なら(たぶん)日本一。PHP 5.3に対応したものはPEARチャンネルGitHubで公開中。

URLhttp://d.hatena.ne.jp/rsky/