Linux 下PHP扩展开发系列:二. 一个典型的扩展开发_PHP教程
看完前言中所说的一些内容后,各位应该对PHP扩展开发有个笼统的了解了,可能有些人会觉得开发扩展很麻烦很复杂,实际上并非如此,这一篇我们就快速进入角色,开发出我们的第一个扩展。
一、编译PHP
开发之前还需要先准备好PHP源码并编译,过程如下:
<span tar</span> -zxvf php-<span 5.3</span>.<span 9</span>.<span tar</span><span .gz cd php</span>-<span 5.3</span>.<span 9</span>
我使用的是php5.3.9,解压后,我们进入了PHP源码目录,然后我们直接编译并增加php.ini:
./configure --prefix=/usr/local/webserver/php --enable-fastcgi --enable-fpm --enable-<span debug </span><span make</span> && <span make</span> <span install</span> <span cp</span> /home/soft/php-<span 5.3</span>.<span 9</span>/php.ini-development /usr/local/webserver/php/lib/php.ini
编译完成,我没有静态编译其他扩展,但是开启了debug,这个后面会用到。然后修改php.ini中对应的项,这里就不细说了。
现在把PHP相关加入环境变量中,省去后面很多工作:
vim /root/.bash_profile
我是使用root,其他不同用户修改对应用户目录下的.bask_profile文件,在文件中的PATH后面加入:/usr/local/webserver/php/bin/,类似下面这样:
PATH=$PATH:$HOME/bin:/usr/local/webserver/php/bin/
环境变量设置好了,我们查看下PHP版本:
OK,编译工作完成,让我们继续。
二、典型开发流程
一个典型的扩展开发流程如下图:
三、扩展功能定义
-2147483648 到 2147483647,与32位系统相同。
四、正式开发
cd /home/soft/php-<span 5.3</span>.<span 9</span>/ext
然后了解下PHP提供的扩展骨架工具ext_skel生成骨架,ext_skel的用法如下:
./ext_skel --extname=module [--proto=<span file</span>] [--stubs=<span file</span>] [--xml[=<span file</span><span ]] [</span>--skel=<span dir</span>] [--full-xml] [--no-<span help] </span>--extname=<span module module is the name of your extension(模块名,会在当前目录创建一个该名称子目录) </span>--proto=<span file</span> <span file</span><span contains prototypes of functions to create(函数原型定义文件) </span>--stubs=<span file</span> generate only <span function</span> stubs <span in</span> <span file</span> --xml generate xml documentation to be added to phpdoc-<span cvs </span>--skel=<span dir</span> path to the skeleton directory(设置骨架生成的目录,不设置该项则默认在ext/<span extname下) </span>--full-xml generate xml documentation <span for</span> a self-<span contained extension (not yet implemented) </span>--no-help don<span '</span><span t try to be nice and create comments in the code</span> and helper functions to test <span if</span> the module compiled (生成的代码中不显示各种帮助注释)
这次我们准备用到两个选项,--extname=myip 即定义扩展的名称,而--proto=myip.pro则是定义扩展的函数原型,首先我们生成扩展函数原型文件:
vim myip.pro
加入以下内容:
<span int</span> ip2long32(<span string</span> ip)
这意味着我们的扩展中有一个函数,返回值为int型,输入为string。
这时候执行以下命令生成扩展骨架:
./ext_skel --extname=myip --proto=myip.pro
OK,这时候你会发现在当前PHP扩展目录下生成了一个子目录myip,进入myip看下:
<span cd myip ll</span>
你会发现生成了一堆文件,如下图:
此时我们就可以进行第二步了。
2. 修改config.m4
关于config.m4文件的功能,我们留到后面的文章中在详细进行说明,现在只说明要做什么。
使用vim编辑config.m4:
vim config.m4
将16至18行行首的dnl去掉,如下:
具体这样做的原因在后面的文章中会说明,这边我们直接退出并保存config.m4,继续进入下一步。
3. 编码
重头戏来啦,终于可以进入myip.c中进行功能的编码了,一起欢呼下吧!
vim myip.c
找到下图所示的位置:
图中就是扩展骨架工具根据我们提供的函数原型生成的对应函数,此处有几个需要注意的地方:
1. PHP_FUNCTION:是PHP核心定义的一个宏,与ZEND_FUNCTION相同,用于定义扩展函数,实际生成的函数名称为zif_ip2long32。
2. zend_parse_parameters:由于PHP为弱类型语言,而C是强类型,因此需要使用该函数用于接收PHP传入的参数,并进行一定的类型转换,将PHP的变量转为C语言能够辨认的类型。
zend_parse_parameters函数的原型如下:
zend_parse_parameters(<span int</span> num_args TSRMLS_CC, <span char</span> *type_spec, …);
参数说明:
- num_args:传递给函数的参数个数。通常的做法是使用宏 ZEND_NUM_ARGS()。
- TSRMLS_CC:线程安全,总是传递TSRMLS_CC宏。 详解:http://www.54chen.com/php-tech/what-is-tsrmls_cc.html
- type_spec:第三个参数是一个字符串,指定了函数期望的参数类型
- ...:需要随参数值更新的变量列表]
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(ip_int32)比较特殊,这也是PHP内核提供的宏,用于返回值给PHP,具体说明如下:
设置返回值并且结束函数 设置返回值 宏返回类型和参数
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) 资源句柄。
编码完成了,保存并退出,然后我们可以开始编译了。
4. 编译
<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>/
进入该目录看下是否已经有myip.so,有的话最后我们就可以修改php.ini载入该so文件
5. 修改php.ini
cd /usr/local/webserver/php/<span lib vim php.ini</span>
修改extension_dir,并加入 extension = myip.so
extension_dir = "/usr/local/webserver/php/lib/php/extensions/debug-non-zts-20090626/"<span extension </span>= myip.so
退出保存,并重启php,如果是使用Phpfpm的话可以执行如下命令:
<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>
说明已经正常载入了,最后我们测试下扩展函数吧!
6. 测试
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>)
如上所示,ip2long32输出的是32位有符号整数,而ip2long输出的是64位无符号整数,大功告成!
五、小结

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

PHP仍然流行的原因是其易用性、靈活性和強大的生態系統。 1)易用性和簡單語法使其成為初學者的首選。 2)與web開發緊密結合,處理HTTP請求和數據庫交互出色。 3)龐大的生態系統提供了豐富的工具和庫。 4)活躍的社區和開源性質使其適應新需求和技術趨勢。

Docker在Linux上重要,因為Linux是其原生平台,提供了豐富的工具和社區支持。 1.安裝Docker:使用sudoapt-getupdate和sudoapt-getinstalldocker-cedocker-ce-clicontainerd.io。 2.創建和管理容器:使用dockerrun命令,如dockerrun-d--namemynginx-p80:80nginx。 3.編寫Dockerfile:優化鏡像大小,使用多階段構建。 4.優化和調試:使用dockerlogs和dockerex

IIS和PHP可以兼容,通過FastCGI實現。 1.IIS通過配置文件將.php文件請求轉發給FastCGI模塊。 2.FastCGI模塊啟動PHP進程處理請求,提高性能和穩定性。 3.實際應用中需注意配置細節、錯誤調試和性能優化。

多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

Laravel優化Web開發流程的方法包括:1.使用路由系統管理URL結構;2.利用Blade模板引擎簡化視圖開發;3.通過隊列處理耗時任務;4.使用EloquentORM簡化數據庫操作;5.遵循最佳實踐提高代碼質量和可維護性。

DMA在C 中是指DirectMemoryAccess,直接內存訪問技術,允許硬件設備直接與內存進行數據傳輸,不需要CPU干預。 1)DMA操作高度依賴於硬件設備和驅動程序,實現方式因係統而異。 2)直接訪問內存可能帶來安全風險,需確保代碼的正確性和安全性。 3)DMA可提高性能,但使用不當可能導致系統性能下降。通過實踐和學習,可以掌握DMA的使用技巧,在高速數據傳輸和實時信號處理等場景中發揮其最大效能。

AI可以幫助優化Composer的使用,具體方法包括:1.依賴管理優化:AI分析依賴關係,建議最佳版本組合,減少衝突。 2.自動化代碼生成:AI生成符合最佳實踐的composer.json文件。 3.代碼質量提升:AI檢測潛在問題,提供優化建議,提高代碼質量。這些方法通過機器學習和自然語言處理技術實現,幫助開發者提高效率和代碼質量。
