ホームページ  >  記事  >  バックエンド開発  >  Hello World: 最初の PHP 拡張機能_PHP チュートリアル

Hello World: 最初の PHP 拡張機能_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 17:47:041108ブラウズ

目標
hello という名前の PHP 拡張機能を作成し、その中に「Hello World」文字列を出力する唯一の関数 hello_world を実装します。

前提条件
C コンパイラー、PHP ランタイム環境、および便利なテキスト エディターがインストールされたコンピューター。
重要な注意事項: Windows では PHP 拡張機能を作成しないでください。Visual C と MinGW のコンパイラは使いにくいため、1 週間以上いじくり回しましたが、Windows では正常にコンパイルできませんでした。したがって、少なくとも Unix 環境で実行してください。 Macおよび各種Linux環境が利用可能です。

PHPソースコードをダウンロード
まず php -v を使用してシステム上の PHP バージョンを確認し、次に対応するソース コード パッケージを php.net からダウンロードします。これを php5-5.3.5 などのディレクトリに解凍します。ソース コード ディレクトリでは、ext ディレクトリにすべての PHP 拡張機能が配置されており、当面は他のディレクトリを考慮する必要はありません。

PHP 拡張機能のフレームワーク コードを生成する
php5-5.3.5/ext ディレクトリには、拡張機能を作成するための便利なツールである ext_skel というファイルがあります。実行権限 (chmod u+x ext_skel) があることを確認し、ターミナルで実行します

リーリー

つまり、初期スケルトン コードを含む hello ディレクトリが ext ディレクトリに作成されます。次のタスクは、hello 拡張機能を作成し、hello_world 関数を実装することです。

config.m4を編集
テキスト エディタで ext/hello/config.m4 を開きます。そこには多くのコメント (dnl で始まる行) が含まれており、基本的に多くの問題を説明しています。ここで行う必要があるのは

を入れることです リーリー

これら 3 行のコメントを外します。このようにして、次のコンパイル中に ./configure --enable-hello を使用して、先ほど作成した拡張機能をコンパイルできます。

設定を再生成
ソース コードのルート ディレクトリに戻り、./buildconf --force を実行して、configure --enable-hello パラメータをアクティブにします。 buildconf の実行時に次のエラーが発生した場合:

リーリー

autoconf-2.13をインストールしてください(ubuntu怠け者の使い方)

リーリー

コンパイル拡張機能
現時点では、hello_world 関数はまだ実装されていませんが、hello 拡張機能はコンパイルできます。最初にコンパイルして、環境構成に問題がないことを確認します。

リーリー

一定の時間が経過した後 (実際には PHP 全体がコンパイルされました)、

を使用します。 リーリー

拡張機能のコンパイルを確認してください。何もなければ、リマインダーを与える必要があります

リーリー

hello_world関数を書く
関数の宣言:

で ext/hello/php_hello.h を開きます
		PHP_MINIT_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>
PHP_MSHUTDOWN_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>
PHP_RINIT_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>
PHP_RSHUTDOWN_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>
PHP_MINFO_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>

后面添加

		PHP_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello_world<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>

即在扩展的头文件中声明了 hello_world 的函数的原型。PHP_FUNCTION 是用来定义 PHP 函数的 C 语言宏。至于宏展开后的样子,几乎不用去想。只管用就可以了。

实现函数:打开 hello.c,在文件的末尾添加

		PHP_FUNCTION<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello_world<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">{</span>
	php_printf<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(255, 0, 0); ">"Hello World"</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(177, 177, 0); ">return</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">}</span>

这里即是 hello_world 函数的实现。php_printf 的作用是向 SAPI 输出一段字符串,类似于 PHP 语言中的 echo。

接下来还需要将 hello_world 函数注册到 zend_module_entry,这样这个函数才能在 PHP 程序中变成“可见”的。找到

		<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(153, 51, 51); ">const</span> zend_function_entry hello_functions<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">[</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">]</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">=</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">{</span>
	PHP_FE<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>confirm_hello_compiled<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span>	NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; ">/* For testing, remove later. */</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">{</span>NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span> NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span> NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">}</span><span style="font-family: Tahoma, sans-serif; line-height: normal; ">/* Must be the last line in hello_functions[] */</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">}</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>

将其修改为:

		<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(153, 51, 51); ">const</span> zend_function_entry hello_functions<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">[</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">]</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">=</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">{</span>
	PHP_FE<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>confirm_hello_compiled<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span>	NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; ">/* For testing, remove later. */</span>
	PHP_FE<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">(</span>hello_world<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span> NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">)</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">{</span>NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span> NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">,</span> NULL<span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">}</span><span style="font-family: Tahoma, sans-serif; line-height: normal; ">/* Must be the last line in hello_functions[] */</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(0, 153, 0); ">}</span><span style="font-family: Tahoma, sans-serif; line-height: normal; color: rgb(51, 153, 51); ">;</span>

此时整个的 hello 扩展的代码就编写完了。最后再来 make 一下。

测试
在终端下运行 sapi/cli/php -r 'hello_world();echo "\n";',如果看到输出“Hello World”,就成功了。

如何把扩展编译成 .so 文件
上面编译的结果是把 hello 扩展编译进了 PHP 核心中。如果想要编译成 .so 扩展,以便发布出去的话。需要使用

./configure --enable-hello=shared
make

这样编译完成后,会在 modules 目录下生成 hello.so 文件。把它复制到你的 PHP 运行环境的 extension_dir 下就可以像其他扩展一样使用了。需要注意的是 PHP 版本。如果你是在 PHP 5.3.5 的源代码环境中编译的扩展,则生成的 .so 文件只能用在 PHP 5.3.5 的运行环境中。

最后提一下,如果对 PHP 扩展有兴趣,可以看看《Extending and Embedding PHP》这本书,作者还是个 MM。目前没有中文版,英文电子版的自己搜。

摘自 lostwolf blog

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/478541.htmlTechArticle目标 创建一个名为 hello 的 PHP 扩展,并实现里面唯一的函数 hello_world,作用是打印出 Hello World 字符串。 前提条件 一台已经安装了 C 编译器...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。