搜索
首页后端开发php教程PHP扩展开发入门教程_PHP教程

PHP扩展开发入门教程_PHP教程

Jul 13, 2016 am 10:06 AM
lphp主要使用入门教程开发扩展文章语言

PHP扩展开发入门教程

 这篇文章主要介绍了PHP扩展开发入门教程,本文讲解了使用C语言在Linux系统下开发一个PHP扩展应该具备的最基本知识,需要的朋友可以参考下

 

 

PHP扩展开发

我准备在此系列博文中总结我有关PHP扩展开发的学习和感悟,力图简单清晰地描述在Linux系统下开发一个PHP扩展应该具备的最基本知识。水平较低,难免有错误,望指出。

准备工作

首先要获取一份PHP源码(可以从Github上签出,或者到官网上下载最新的稳定版),然后编译之。为了加快编译速度,我们推荐禁用所有额外的扩展(使用--disable-all选项),但最好打开debug(使用--enable-debug选项)和线程安全(使用--enable-maintainer-zts),但要在发布扩展的时候关闭debug,视情况选择是否需要打开线程安全:

代码如下:


$ ./buildconf --force
$ ./configure --disable-all --enable-debug --enable-maintainer-zts
$ make
注意,我们没有指定--prefix选项(同时也没有make install),因为这不是必须的。注意查看输出信息,也许你需要安装一些依赖包才能成功编译PHP。

 

编译后的PHP的可执行程序在源码的sapi目录下,对应不同的宿主环境有不同的子目录,我们以后都主要使用cli(command line interface)环境,可以建一个别名方便引用:

代码如下:


$ alias php-dev=/usr/local/src/php-5.6.5/sapi/cli/php

 

有一些命令行选项是很有用的:

代码如下:


php-dev -h          # 打印帮助信息
php-dev -v          # 打印版本信息
php-dev --ini        # 打印配置信息
php-dev -m          # 打印加载的模块信息
php-dev -i          # phpinfo
php-dev -r       # 执行code里的代码 <p> </p> <p>扩展骨架</p> <p>PHP的所有官方扩展都在源码的ext目录下,我们自己写的扩展也可以放在该目录下。注意,该目录下有个名为ext_skel的shell脚本,它是用来生成PHP扩展骨架的,使用该脚本,可以帮我们快速创建PHP扩展:</p> <p>代码如下:</p> <div id="code79500"> <br> $ ./ext_skel --extname=myext <br> 上面的命令帮我们创建了一个名为myext的扩展,源码在myext目录下。不带任何参数的执行该脚本可以打印帮助信息,这样你可以查看到该脚本提供的更多选项。 <p> </p> <p>接下来让我们完成我们的扩展。进入myext目录,编辑config.m4配置文件,找到PHP_ARG_ENABLE宏函数,去掉前面的dnl注释(共三行)。退回到源码根目录,重新执行buildconf、configure和make命令:</p> <p>代码如下:</p> <div id="code60938"> <br> $ ./buildconf --force<br> $ ./configure --help | grep myext<br> --enable-myext Enable myext support<br> $ ./configure --disable-all --enable-myext --enable-debug --enable-maintainer-zts<br> $ make <p> </p> <p>注意,我们用./configure --help | grep myext打印了我们扩展的加载情况,如果看不到下面的输出,则说明我们的扩展没有配置成功,回头检查下config.m4文件。</p> <p>这次编译应该非常快,因为大部分代码都已经编译过了。PHP还有另外一种编译扩展的方法(使用动态连接的方式,将扩展编译为.so的文件),不过我们推荐在开发扩展的时候使用静态编译,因为这样省去了在配置文件中加载扩展的步骤。</p> <p>一切顺利的话,我们的第一个扩展就已经可以执行了:</p> <p>代码如下:</p> <div id="code43184"> <br> $ php-dev -m | grep myext<br> myext<br> $ php-dev -r 'echo confirm_myext_compiled("myext") . "\n";'<br> Congratulations! You have successfully modified ext/myext/config.m4. Module myext is now compiled into PHP. <br> 第一个命令显示了我们的扩展已经被加载。第二个命令执行了ext_skel扩展骨架自动为我们创建的函数。当然,这个函数毫无意义,不过我们可以很容易的把这个函数改编成hello world。 <p> </p> <p>手动创建扩展</p> <p>大部分教程都是以ext_skel扩展骨架为原型讲述扩展开发的,这种做法当然很方便快捷。但是我个人更喜欢纯手工开发扩展的方式,因为这样更容易理解其中的每一个细节。</p> <p>手动创建扩展,先进入ext目录,创建我们的扩展目录myext2。有几个文件是必须的:config.m4,myext2.c和php_myext2.h。</p> <p>首先,我们来编写配置文件config.m4:</p> <p>代码如下:</p> <div id="code69887"> <br> PHP_ARG_ENABLE(myext2, whether to enable myext2 support,<br> [ --enable-myext2 Enable myext2 support]) <p> </p> <p>if test "PHP_MYEXT2" != "no"; then<br> PHP_NEW_EXTENSION(myext2, myext2.c, $ext_shared)<br> fi</p> <br> config.m4其实是autoconf程序使用的配置文件,autoconf是autotools工具箱里重要的组成。完整介绍autoconf的用法是需要很长时间的,好在我们这里的用法非常简单。 <p> </p> <p>PHP_ARG_ENABLE是PHP为autoconf定义的宏函数,myext2是它的第一个参数,指出了扩展的名字;后面两个参数只是在make和configure执行时用来显示的,所以我们可以随便写。[ ]在autoconf语法中的作用类似于双引号,用来包裹字符串(注意第二个参数中包含了空格,但是可以不用方括号起来)。还有第四个参数用来指明扩展默认是开启还是关闭(yes或no),默认是no。</p> <p>下面三行其实就是shell语法,判断我们是否开启了PHP_MYEXT2扩展模块。如果开启了该扩展模块(--enable-myext2),则$PHP_MYEXT2变量的值不为no,因此执行PHP_NEW_EXTENSION宏。这个宏函数也是PHP为autoconf定义的扩展语法,第一个参数同样是扩展名称;第二个参数是扩展要编译的C文件,如果有多个,依次写下去就可以了(空格分隔);第三个参数固定是$ext_shared。</p> <p>接下来编写php_myext2.h头文件,该文件的命名是PHP扩展的规范 — php_扩展名.h:</p> <p>代码如下:</p> <div id="code89777"> <br> #ifndef PHP_MYEXT2_H<br> #define PHP_MYEXT2_H <p> </p> <p>extern zend_module_entry myext2_module_entry;<br> #define phpext_myext2_ptr &myext2_module_entry</p> <p>#define PHP_MYEXT2_VERSION "0.1.0"</p> <p>/* prototypes */<br> PHP_FUNCTION(hello);</p> <p>#endif /* PHP_MYEXT2_H */</p> <p> </p> <p>这里主要的代码是定义了名为phpext_myext2_ptr的宏,PHP底层通过该宏来引用我们的扩展。可以看出,该宏的命名同样是有规范的 — phpext_扩展名_ptr。而myext2_module_entry是我们稍后要在.c文件里定义的结构体,它的命名也是规范的 — 扩展名_module_entry。</p> <p>此外我们还定义了一个标识我们扩展版本号的宏和一个函数原型(通过PHP_FUNCTION宏,PHP_FUNCTION宏函数的参数是外部可使用的函数名),稍后我们会来实现这个函数。</p> <p>最后来看下myext2.c文件的实现:</p> <p>代码如下:</p> <div id="code56665"> <br> #include "php.h"<br> #include "php_myext2.h" <p> </p> <p>/* {{{ myext2_functions[]<br> *<br> * Every user visible function must have an entry in myext2_functions[].<br> */<br> static const zend_function_entry myext2_functions[] = {<br> PHP_FE(hello, NULL)<br> PHP_FE_END<br> };<br> /* }}} */</p> <p>/* {{{ myext2_module_entry<br> */<br> zend_module_entry myext2_module_entry = {<br> STANDARD_MODULE_HEADER,<br> "myext2", /* module name */<br> myext2_functions, /* module functions */<br> NULL, /* module initialize */<br> NULL, /* module shutdown */<br> NULL, /* request initialize */<br> NULL, /* request shutdown */<br> NULL, /* phpinfo */<br> PHP_MYEXT2_VERSION, /* module version */<br> STANDARD_MODULE_PROPERTIES<br> };<br> /* }}} */</p> <p>#ifdef COMPILE_DL_MYEXT2<br> ZEND_GET_MODULE(myext2)<br> #endif</p> <p>/* {{{ proto void hello()<br> Print "hello world!" */<br> PHP_FUNCTION(hello)<br> {<br> php_printf("hello world!\n");<br> }<br> /* }}} */</p> <p> </p> <p>对比下扩展骨架创建的.c文件就会发现,我们的.c文件非常的简单,其实这些对一个最基本的扩展来说就已经足够了。</p> <p>上面的代码是简单而清晰的,大部分注释已经很具说明性了。我们再简要概括下:</p> <p>1.开头包含我们要用到的头文件。php.h是必须的,它已经帮我们包含了我们会用到的绝大多数的标准库文件,比如stdio.h,stdlib.h等等。<br> 2.myext2_functions定义了由我们要暴露出去的函数构成的结构体数组,每一个元素通过PHP_FE宏来指定。PHP_FE宏有两个参数,第一个是外部可使用的函数名,第二个是参数信息(这里我们简单使用了NULL),最后一个元素必须是PHP_FE_END。注意它的注释,再次强调,每一个要暴露给外部使用的函数,都必须在该结构体数组中有定义。<br> 3.myext2_module_entry定义了我们的模块信息,它是一个结构体,大部分属性都已经通过注释给出了说明。注意中间的五个函数指针,我们都简单的置为了NULL,在后续的博文中会讲述它们的用法。<br> 4.ZEND_GET_MODULE(myext2)宏函数是被ifdef宏包含的,所以说它是否调用是视情况而定的。至于什么情况下会被调用,什么情况下不会被调用,在后续的博文中会讲述。<br> 5.最后几行代码我们实现了hello函数,它很简单,调用php_printf输出hello world!跟一个换行符,php_printf的用法和printf完全一样。<br> 6.注释里的 {{{ 和 }}} 是为了方便vim等编辑器折叠而使用的,我们推荐你也这样来写注释。<br> 这里面涉及了一些宏,比如PHP_FE,PHP_FE_END,PHP_FUNCTION等等,完整介绍这些宏要到后续的博文中才可以,眼下最简单的办法就是记住这些宏。</p> <p>注意到我们每一个文件的命名,变量的命名,空格和缩进,以及注释等都是非常规范的,遵循这些规范,可以使我们编写的代码和PHP本身的代码更加契合,我们也推荐你使用这样的规范来开发PHP扩展。</p> <p>最后,编译运行我们的扩展:</p> <p>代码如下:</p> <div id="code56002"> <br> $ ./buildconf --force<br> $ ./configure --help | grep myext2<br> --enable-myext2 Enable myext2 support<br> $ ./configure --disable-all --enable-myext2 --enable-debug --enable-maintainer-zts<br> $ make <p> </p> <p>$ php-dev -m | grep myext2<br> myext2<br> $ php-dev -r 'hello();'<br> hello world!</p> <p align="left"></p> <div style="display:none;"> <span id="url" itemprop="url">http://www.bkjia.com/PHPjc/961082.html</span><span id="indexUrl" itemprop="indexUrl">www.bkjia.com</span><span id="isOriginal" itemprop="isOriginal">true</span><span id="isBasedOnUrl" itemprop="isBasedOnUrl">http://www.bkjia.com/PHPjc/961082.html</span><span id="genre" itemprop="genre">TechArticle</span><span id="description" itemprop="description">PHP扩展开发入门教程 这篇文章主要介绍了PHP扩展开发入门教程,本文讲解了使用C语言在Linux系统下开发一个PHP扩展应该具备的最基本知识,需...</span> </div> </div> <div class="art_confoot"></div> </div> </div> </div> </div> </div> </div>
声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
超越炒作:评估当今PHP的角色超越炒作:评估当今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在现代编程中仍然是一个强大且广泛使用的工具,尤其在web开发领域。1)PHP易用且与数据库集成无缝,是许多开发者的首选。2)它支持动态内容生成和面向对象编程,适合快速创建和维护网站。3)PHP的性能可以通过缓存和优化数据库查询来提升,其广泛的社区和丰富生态系统使其在当今技术栈中仍具重要地位。

PHP中的弱参考是什么?什么时候有用?PHP中的弱参考是什么?什么时候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通过WeakReference类实现的,不会阻止垃圾回收器回收对象。弱引用适用于缓存系统和事件监听器等场景,需注意其不能保证对象存活,且垃圾回收可能延迟。

解释PHP中的__ Invoke Magic方法。解释PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允许对象像函数一样被调用。1.定义\_\_invoke方法使对象可被调用。2.使用$obj(...)语法时,PHP会执行\_\_invoke方法。3.适用于日志记录和计算器等场景,提高代码灵活性和可读性。

解释PHP 8.1中的纤维以进行并发。解释PHP 8.1中的纤维以进行并发。Apr 12, 2025 am 12:05 AM

Fibers在PHP8.1中引入,提升了并发处理能力。1)Fibers是一种轻量级的并发模型,类似于协程。2)它们允许开发者手动控制任务的执行流,适合处理I/O密集型任务。3)使用Fibers可以编写更高效、响应性更强的代码。

PHP社区:资源,支持和发展PHP社区:资源,支持和发展Apr 12, 2025 am 12:04 AM

PHP社区提供了丰富的资源和支持,帮助开发者成长。1)资源包括官方文档、教程、博客和开源项目如Laravel和Symfony。2)支持可以通过StackOverflow、Reddit和Slack频道获得。3)开发动态可以通过关注RFC了解。4)融入社区可以通过积极参与、贡献代码和学习分享来实现。

PHP与Python:了解差异PHP与Python:了解差异Apr 11, 2025 am 12:15 AM

PHP和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

php:死亡还是简单地适应?php:死亡还是简单地适应?Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不断适应和进化。1)PHP从1994年起经历多次版本迭代,适应新技术趋势。2)目前广泛应用于电子商务、内容管理系统等领域。3)PHP8引入JIT编译器等功能,提升性能和现代化。4)使用OPcache和遵循PSR-12标准可优化性能和代码质量。

PHP的未来:改编和创新PHP的未来:改编和创新Apr 11, 2025 am 12:01 AM

PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能