序文で述べた内容をいくつか読めば、PHP 拡張機能の開発について一般的に理解できるはずです。実際には、この記事ではそうではありません。をロールに組み込み、最初の拡張機能を開発しました。
1. PHP をコンパイルします
開発前に、PHP ソースコードを準備してコンパイルする必要があります。プロセスは次のとおりです。 リーリー
私はphp5.3.9を使用しています。解凍後、PHPソースコードディレクトリに入り、php.iniを直接コンパイルして追加しました。 リーリー他の拡張機能は静的にコンパイルしませんでしたが、後で使用するデバッグをオンにしました。次に、php.ini 内の対応する項目を変更します。ここでは詳しく説明しません。
ここで、後で多くの作業を節約するために、PHP 関連の情報を環境変数に追加します。
リーリー私は root を使用し、他の別のユーザーは対応するユーザー ディレクトリ内の .bask_profile ファイルを変更し、次のようにファイル内の PATH の後に /usr/local/webserver/php/bin/ を追加します。
リーリー環境変数が設定されたので、PHPのバージョンを確認してみましょう:
OK、コンパイル作業は完了しました。続行しましょう。
2. 一般的な開発プロセス
典型的な拡張機能の開発プロセスは以下のとおりです:
3. 拡張関数の定義
、32 ビット システムと同じ。
次に、スケルトンを生成するために PHP が提供する拡張スケルトン ツール ext_skel について学習します。 ext_skel の使用方法は次のとおりです。
リーリー
リーリー
リーリー
リーリー
リーリー
この時点で、2 番目のステップに進むことができます。
config.m4 ファイルの機能については、後の記事で詳しく説明することにします。ここでは、何をするのかだけ説明します。
リーリー
メインイベントはここです。ついに myip.c に入って関数をコーディングできるようになります。一緒に乾杯しましょう!
リーリー
下の写真に示されている場所を見つけてください:
1. PHP_FUNCTION: PHP コアによって定義されるマクロであり、ZEND_FUNCTION と同じであり、実際に生成される関数名は zif_ip2long32 です。
リーリー
我们将该函数修改为如下内容: 功能完成了,这边有个RETURN_LONG(ip_int32)比较特殊,这也是PHP内核提供的宏,用于返回值给PHP,具体说明如下: 设置返回值并且结束函数 设置返回值 宏返回类型和参数 编码完成了,保存并退出,然后我们可以开始编译了。 4. 编译 不出意外的话编译完成后会有如下提示: 进入该目录看下是否已经有myip.so,有的话最后我们就可以修改php.ini载入该so文件 5. 修改php.ini 修改extension_dir,并加入 extension = myip.so 退出保存,并重启php,如果是使用Phpfpm的话可以执行如下命令: 看下扩展是否正常载入: 说明已经正常载入了,最后我们测试下扩展函数吧! 6. 测试 如上所示,ip2long32输出的是32位有符号整数,而ip2long输出的是64位无符号整数,大功告成! 五、小结
type_spec是格式化字符串,其常见的含义如下:
参数 代表着的类型
b Boolean
l Integer 整型
d Floating point 浮点型
s String 字符串
r Resource 资源
a Array 数组
o Object instance 对象
O Object instance of a specified type 特定类型的对象
z Non-specific zval 任意类型~
Z zval**类型
f 表示函数、方法名称
<span PHP_FUNCTION(ip2long32)
{
</span><span char</span> *ip =<span NULL;
</span><span int</span> argc =<span ZEND_NUM_ARGS();
</span><span int</span><span ip_len;
</span><span if</span> (zend_parse_parameters(argc TSRMLS_CC, <span "</span><span s</span><span "</span>, &ip, &ip_len) ==<span FAILURE) {
</span><span return</span><span ;
}
int32_t ip_int32;
unsigned </span><span char</span><span ip1, ip2, ip3, ip4;
sscanf(ip, </span><span "</span><span %hhu.%hhu.%hhu.%hhu</span><span "</span>, &ip1, &ip2, &ip3, &<span ip4);
ip_int32 </span>= (int32_t)((ip1 << <span 24</span>) | (ip2 << <span 16</span>) | (ip3 << <span 8</span>) |<span ip4);
RETURN_LONG(ip_int32);
}</span>
RETURN_LONG(l) RETVAL_LONG(l) 整数
RETURN_BOOL(b) RETVAL_BOOL(b) 布尔数(1或0)
RETURN_NULL() RETVAL_NULL() NULL
RETURN_DOUBLE(d) RETVAL_DOUBLE(d) 浮点数
RETURN_STRING(s, dup) RETVAL_STRING(s, dup) 字符串。如果dup为1,引擎会调用estrdup()重复s,使用拷贝。如果dup为0,就使用s
RETURN_STRINGL(s, l, dup) RETVAL_STRINGL(s, l, dup) 长度为l的字符串值。与上一个宏一样,但因为s的长度被指定,所以速度更快。
RETURN_TRUE RETVAL_TRUE 返回布尔值true。注意到这个宏没有括号。
RETURN_FALSE RETVAL_FALSE 返回布尔值false。注意到这个宏没有括号。
RETURN_RESOURCE(r) RETVAL_RESOURCE(r) 资源句柄。<span phpize
.</span>/configure --with-php-config=/usr/local/webserver/php/bin/php-<span config
</span><span make</span> && <span make</span> <span install</span>
Installing shared extensions: /usr/local/webserver/php/lib/php/extensions/debug-non-zts-<span 20090626</span>/
cd /usr/local/webserver/php/<span lib
vim php.ini</span>
extension_dir = "/usr/local/webserver/php/lib/php/extensions/debug-non-zts-20090626/"<span
extension </span>= myip.so
<span kill</span> -USR2 `<span cat</span> /usr/local/webserver/php/var/run/php-fpm.pid`
[root@tm977 lib]# php -m|<span grep</span><span myip
myip</span>
php -r <span "</span><span var_dump(ip2long32('192.168.1.1'));</span><span "</span>
<span int</span>(-<span 1062731519</span><span )
php </span>-r <span "</span><span var_dump(ip2long('192.168.1.1'));</span><span "</span>
<span int</span>(<span 3232235777</span>)