Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

PHPエクステンションでクラスを作成する

PHPエクステンションの作り方 第4回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2013/10/28 14:00

 本連載では、PHPエクステンションの作成方法を紹介します。前回までは、PHPエクステンションの基本的な作成方法から、関数の作成方法までを紹介しました。今回からはクラスを作成していきます。初回の今回は、PHPエクステンションでクラスを作成する流れとその全体の構造を紹介します。

目次

対象読者

 PHPでの基本構文を理解している方で、PHPエクステンションに興味がある方、さらに深くPHPを知りたい方で、C言語の基本的な構文を理解している方を対象としています。

必要な環境

 この記事では、PHP 5.4を使用し、Linux環境で確認を行っています。インストール方法は初回を参照してください。

作成するクラスの概要

 クラス定義の全体像を紹介する前に、実際に簡単なクラスの作成方法を通じて手順を紹介します。よりイメージしやすいように、Zipアーカイブを扱うクラスを想定して作成します。しかしながら、まだ何のメソッドもありません。これをPHPで作成してみた場合のイメージを以下に示します。

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の中身を以下に示します。

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の内容も下記に示します。

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マクロを使って作成した関数を実行します。

pzip.c内のモジュール初期化部分の定義
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マクロで作成される関数の引数が設定されます。マクロばかりでよく内容が見えませんが、あまり深く考えずに決まりとして覚えてしまっても問題ありません。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。個人紹介主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしど...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:PHPエクステンションの作り方
All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5