PHP Extensionのスタブ生成ツール「PHPH」を作った

PHPファイルからPHP Extensionの雛形を生成するツール「PHPH」を作った。
 
CodeGen_PECLは、
・実装するクラスのプロトタイプを、CodeGen_PECLの形式に沿ったXMLで作成。
・メソッドの中身をXMLファイル内で実装。
PHP Extensionソースに変換。
 
PHPHは、
・実装するクラスのプロトタイプを、PHPファイルで作成。
PHP Extensionソースに変換。
・メソッドの中身をCファイル内で実装。
 
PHPH \ パッケージ \ Openpear
http://openpear.org/package/PHPH
 
(ここだけの話、CodeGen_PECLがあんまり好きじゃなく)
以下、現在最新のドキュメント。
 

PHPH - Cヘッダとスタブファイルジェネレータ

phphは、PHPファイルからPHP Extension用のCヘッダファイルとCソースファイルを作成します。
 

形式

phph init ext_name [prototype_file ..]
phph update [options]
phph template [method_name ..]
phph make
phph make install
phph make clean
 

コマンド解説

init

プロジェクトを作成します。
Extension名は、[a-z0-9_]+です。
コマンドを実行したディレクトリ以下にExtension名のディレクトリが作成されます。
プロトタイプファイルを指定した場合、ext_name/prototype_filesディレクトリにコピーされます。
 

update

プロトタイプファイルからファイルを更新します。
prototype_files内のファイルを更新した際に実行してください。
Cヘッダファイル/Cソースファイル/確認スクリプトは常に上書きされ、Cスタブファイルは上書きするか否かを対話で決定します。
Cスタブファイルを上書きした場合、backup_filesディレクトリにバックアップファイルが作成されます。
このコマンドは、phphプロジェクトのルートディレクトリで実行します。
 

template

Cスタブファイルの内容を出力します。
method_nameの指定があった場合、method_nameに合ったPHP_METHOD/PHP_FUNCTIONの雛形のみを出力します。
クラスとメソッドの区切りは::です。
このコマンドは、phphプロジェクトのルートディレクトリで実行します。
 

make

Extensionをmakeします。
このコマンドは、以下と同等です。

$ phpize && ./configure && make

 

make install

Extensionをmake installします。
このコマンドは、以下と同等です。

$ make install

通常、root権限が必要になります。
 

make clean

makeしたファイルを削除します。
このコマンドは、以下と同等です。

$ make clean

 

ディレクトリ構造

ext_name/               プロジェクトのルートディレクトリ
|-- .phph               PHPHプロジェクトの設定ファイル
|-- backup_files        updateを実行した際に生成されるCスタブファイルのバックアップファイル
|-- config.m4           Unix用のビルド設定ファイル
|-- config.w32          Windows用のビルド設定ファイル
|-- ext_name.c          Cスタブファイル
|-- ext_name.dsp        Visual C++のプロジェクトファイル
|-- ext_name.php        インストール後のExtension読み込み/定義確認スクリプト
|-- php_ext_name.c      Cソースファイル
|-- php_ext_name.h      Cヘッダファイル
|-- prototype_files     PHPで記述されたプロトタイプファイル
`-- tests               テストスクリプト
    `-- 001.phpt

 

プロトタイプファイルの書き方

PHP Extensionとして実装するクラスやメソッドを定義したPHPファイルを、prototype_filesディレクトリ内に作成します。
 

プロトタイプ定義で対応している修飾子やキーワード
Class

abstract
final
extends
implements
 

Method

public
protected
private
static
abstract
final
Type Hinting
 

Const

-
 

Function

Type Hinting
 

Define

-
 

引数の型指定

PHPでは(ネイティブの)型の指定が出来ない為、引数名で表現します。
型を指定して引数を取るには、$[型表現文字]_[引数名]とします。
型表現文字がない場合、zが適用されます。
プロトタイプで参照渡し指定があり、オブジェクト以外の型表現文字が指定されていた場合、zが適用されます。
 
型表現文字は以下の通りです。

identifier: expected type       required argument number and types
'l': integer                    1: long *
'd': float                      1: double *
's': binary string              2: char **, int *
'S': binary string (strict)     2: char **, int *
'u': Unicode string             2: UChar **, int *
'U': Unicode string (strict)    2: UChar **, int *
't': string (by semantics)      3: zstr *, int *, zend_uchar *
'T': string (no conversion)     3: zstr *, int *, zend_uchar *
'b': boolean                    1: zend_bool *
'r': resource                   1: zval **
'a': array                      1: zval **
'h': array                      1: HashTable **
'o': object                     1: zval **
'O': object (class specified)   2: zval **, zend_class_entry *
'C': string (class name)        1: zend_class_entry **
'f': callback                   2: zend_fcall_info *, zend_fcall_info_cache *
'z': any                        1: zval **
'Z': any                        1: zval ***
'v': varargs (optional)         2: zval ****, int *
'V': varargs (required)         2: zval ****, int *
note:
  varargs (zval ***) should be freed with efree()
  if varargs is used, PHP5.3 or later required.

http://d.hatena.ne.jp/rsky/20071104/1194164491より転載/改変)
 

インストール

# pear install openpear/PHPH-alpha

 

作成の流れ

$ vi prototype.php

<?php
class testext1
{
	public function helloworld() {}
	public function sum($l_value1, $l_value2) {}
}

$ phph init testext1 prototype.php
$ cd testext1/
$ vi testext1.c

@@ -119,7 +119,8 @@
 		return;
 	}
 
-	// ...
+	printf("HelloWorld!\n");
+	return;
 }
 
 // testext1->sum($value1, $value2);
@@ -132,7 +133,7 @@
 		return;
 	}
 
-	// ...
+	RETURN_LONG(value1 + value2);
 }

$ phph make
$ sudo phph make install
$ php testext1.php