ダウンロード サンプルファイル (6.7 KB)
本連載では、PHPエクステンションの作成方法を紹介します。前回までは、PHPエクステンションの基本的な作成方法から、関数の作成方法までを紹介しました。今回からはクラスを作成していきます。初回の今回は、PHPエクステンションでクラスを作成する流れとその全体の構造を紹介します。
対象読者
PHPでの基本構文を理解している方で、PHPエクステンションに興味がある方、さらに深くPHPを知りたい方で、C言語の基本的な構文を理解している方を対象としています。
必要な環境
この記事では、PHP 5.4を使用し、Linux環境で確認を行っています。インストール方法は初回を参照してください。
作成するクラスの概要
クラス定義の全体像を紹介する前に、実際に簡単なクラスの作成方法を通じて手順を紹介します。よりイメージしやすいように、Zipアーカイブを扱うクラスを想定して作成します。しかしながら、まだ何のメソッドもありません。これをPHPで作成してみた場合のイメージを以下に示します。
// Zipアーカイブファイルを扱うクラスを想定
class PZipFile{
}
// Zipアーカイブファイル中の一つのファイル(データ)を扱うクラスを想定
class PZipEntry{
}
好みに左右される部分もありますが、より一般的なクラス管理に近いように、1つのクラス作成ごとに1つのファイルで実装をします。クラスは2つほどありますので、2つのファイルを作成します。もし、2つ以上のクラスを作成することになったとしても、同様の方法で追加していけば問題ありません。では、実際にエクステンションの作成を行います。
クラス作成の手順
PHPであれば、空のクラスを作成する処理はほんの2行で終わってしまいますが、エクステンションとなるとそうはいきません。とはいえ一度流れを覚えてしまえば、記述コードは多いものの、ほとんどのクラス作成で共通です。ここで間違えると後々面倒になるので、復習の意味もかねてモジュールの作成からビルド、そして実行までの手順を紹介します。
ファイルの雛形の作成
ファイルの雛形の作成方法については初回でも紹介しましたが、以下に改めて作成するための方法を記述します。今回は”pzip”というモジュール名にしました。
$/usr/local/src/php-5.4.16/ext/ext_skel --extname=pzip --skel=/usr/local/src/php-5.4.16/ext/skeleton/
クラスファイルの作成
それぞれのクラス定義に相当するように、2つのファイルを作成します。
- pzip_file.c(PZipFileクラスを定義するCファイル)
- pzip_entry.c(PZipEntryクラスを定義するCファイル)
まずは、pzip_file.cの中身を以下に示します。
#ifdef HAVE_CONFIG_H
#include "config.h"
// : (省略)
#include "php_pzip.h"
zend_class_entry *pzip_file_ce; // ……(1)
const zend_function_entry pzip_file_methods[] = { // ……(2)
{NULL, NULL, NULL}
};
PHP_MINIT_FUNCTION(pzip_file){ // ……(3)
zend_class_entry ce; // ……(4)
INIT_CLASS_ENTRY(ce,"PZipFile",pzip_file_methods); // ……(5)
pzip_file_ce = zend_register_internal_class(&ce TSRMLS_CC); // ……(6)
return SUCCESS;
}
(1)のように1つのクラス定義につき、1つのzend_class_entry構造体を用意します。次に、(2)のように関数定義と同様にzend_function_entry構造体も用意します。クラス定義では、ここにメソッドを登録していきます。まだ、メソッド、プロパティもないクラスなので実体もないのですが、ここまでがクラス定義の実体の部分です。
続いて、(3)のPHP_MINIT_FUNCTIONマクロはクラス定義をモジュールに登録する際に実行される部分の記述です。このマクロで作成される関数を通じてモジュールへのクラス登録を行います。まず、一時的に(4)zend_class_entryの変数を用意し、そこに(5)INIT_CLASS_ENTRYマクロを利用しクラス名の設定と(2)で定義したメソッドを追加します。
そして、最後に(6)zend_register_internal_classを使って(1)で用意した変数へと設定する流れになります。
同様に、pzip_entry.cの内容も下記に示します。
zend_class_entry *pzip_entry_ce;
const zend_function_entry pzip_entry_methods[] = {
{NULL, NULL, NULL}
};
PHP_MINIT_FUNCTION(pzip_entry){
zend_class_entry ce;
INIT_CLASS_ENTRY(ce,"PZipEntry",pzip_entry_methods);
pzip_entry_ce = zend_register_internal_class(&ce TSRMLS_CC);
return SUCCESS;
}
クラス名の設定や変数名以外はほぼ同様です。
メインプログラムへの登録
先ほどの2つのプログラムは、そのままの状態では実際にモジュールには登録されません。モジュールに登録するには、ext_skelコマンドで作成されたpzip.cファイル内にあるモジュールの初期化処理の部分で先ほどのPHP_MINIT_FUNCTIONマクロを使って作成した関数を実行します。
PHP_MINIT_FUNCTION(pzip)
{
// クラスごとに以下の行を記述する
PHP_MINIT(pzip_file)(INIT_FUNC_ARGS_PASSTHRU); // ……(1)
PHP_MINIT(pzip_entry)(INIT_FUNC_ARGS_PASSTHRU); // ……(2)
return SUCCESS;
}
(1)、(2)定義の時に作成したマクロはPHP_MINIT_FUNCTIONですが、実行時に使用するマクロはPHP_MINITになります。また、INIT_FUNC_ARGS_PASSTHRUはPHP_MINIT_FUNCTIONマクロで作成される関数の引数が設定されます。マクロばかりでよく内容が見えませんが、あまり深く考えずに決まりとして覚えてしまっても問題ありません。
この記事は参考になりましたか?
- PHPエクステンションの作り方連載記事一覧
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)
< WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
