PHP(Windows)で独自の拡張DLLを作成

実行環境

Windows2008R2(64bit)
IIS
PHP5.4.31の非スレッドセーフ版(IIS を使う場合は、非スレッドセーフ版の PHPのほうが安定しているらしい)
環境構築の為にダウンロードしたファイルは(php-5.4.31-nts-Win32-VC9-x86.zip)

開発環境

PHP5.4.31のソース等が入手できなかったため5.4.33のそれをダウンロード

php-5.4のダウンロードサイト

「Download source code」よりphp-5.4.33-src.zipをダウンロード

「VC9 x86 Non Thread Safe」-「Zip」よりphp-5.4.33-nts-Win32-VC9-x86.zipをダウンロード

clip_1ii

php-5.4.33-nts-Win32-VC9-x86.zipをC:\phpに展開。
(C:\phpにはパスを通す)

php-5.4.33-src.zipをC:\php-srcに展開。

Cygwin

拡張dllのフレームワークの作成等にCygwinのコマンドを使用するのでC:\Cygwinにインストール

Cygwinのサイトよりsetup-x86.exeをダウンロードしてセットアップ実行

必用なモジュールが不明だったのでフルインストールを実行したが、texlive-collection-basic.shのインストールで止まってしまった。

フルインストールをやめてデフォルトインストールをしたが、これでも同様にインストールが完了しなかった。

一応、今回の必用なモジュールはインストールされたようなので、深くは追求しない。

VC

VisualStudio2008はあらかじめインストール済

※別途SDKはインストールしていない

拡張DLLのテンプレートを作成

Visual Studio 2008コマンドプロンプトを開いてカレントをC:\php-src\extに移動して以下のコマンドを実行
※php_test.dllを作成するためのプロジェクトワークスペースが作成される

php ext_skel_win32.php --extname=test

config.w32ファイルの編集

C:\php-src\ext\test\config.w32を以下に従って編集

// $Id$
// vim:ft=javascript

ARG_ENABLE("test", "enable test support", "no");

if (PHP_TEST != "no") {
	EXTENSION("test", "test.c");
}

configure


C:\php-srcをカレントにして以下のコマンドを実行

buildconf
configure

正しく実行されればC:\php-src/main/config.w32.hが作成される

C:\php-src\ext\test

プロジェクトの設定とコンパイル

VCでC:\php-src\ext\test\test.dspを開く。
(test.dspはVC6用のプロジェクトファイルなのでVC2008用に変換)

アクティブなプロジェクトをRelease_TSに設定

追加のライブラリプロジェクトにC:\php\devを追加

スクリーンショット 2014-09-22 17.19.25

プリコンパイルプロセッサからZTS=1を削除
(スレッドセーフの時は不要)

スクリーンショット 2014-09-22 16.57.57

参照するライブラリをphp5ts.libからphp5.libに変更
(スレッドセーフの時は不要)

clip_2

以上の設定完了後、コンパイルを実行するとC:\php-src\ext\php_text.sllが作成される

関数の追加

関数Procを追加(引数には数値と文字)

php_test.h

以下を追加

PHP_FUNCTION(Proc);

test.c

test_functions[]にProcを追加

const zend_function_entry test_functions[] = {
	PHP_FE(Proc,	NULL)
	PHP_FE_END	/* Must be the last line in test_functions[] */
};

引数で受けた数値と文字列より文字列に変換して返す関数の実態

PHP_FUNCTION(Proc)
{

	char *arg = NULL;
	int arg_len, len;
	long n;
	char *strg;
	

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &n, &arg, &arg_len) == FAILURE) {
		return;
	}

	len = spprintf(&strg, 0, "number=%d string=%s", n, arg);
	RETURN_STRINGL(strg, len, 0);
}

以上でリコンパイル

DLLの検証

php_test.dllを実行環境のD:\php\extにコピー

php.iniに以下を追加

extension=php_test.dll

関数の呼び出しをコーディング

$s=Proc(100, "tarum");
echo($s);

以上で正しく動作される

参考サイト


単純な PHP エクステンションの開発方法