当前位置: 首页 > 后端技术 > PHP

PHP扩展开发教程1-相关开发技术比较介绍

时间:2023-03-30 06:01:37 PHP

PHP扩展是高级PHP程序员必须掌握的技能之一。对于一个刚刚入门的PHP扩展开发者来说,如何才能开发出成熟的扩展,进入PHP开发的高级领域呢?本系列开发教程将带您从初级到高级。本教程系列在linux下开发(推荐centos),php版本使用5.6,假设你有一定的linux操作经验和c/c++基础。如果大家有什么问题需要交流,欢迎加入QQ技术交流群32550793与我交流。有几种开发php扩展的技术方法和框架。对于初学者来说,最好选择一个最容易上手、最快见效的框架,这样可以增强学习的兴趣。下面我们将各种技术框架一一对比,让大家找到最适合自己的。1、使用ext-skelC语言开发ext-skel是PHP官方源码中提供的一个php扩展生成工具,可以在c语言框架中生成php扩展的骨架。PHP官方对扩展开发者非常不友好。源代码中提供的ZendAPI极难使用。API复杂而凌乱,充满了各种宏的写法。ZendAPI的坑很多,普通开发者很容易踩坑。出现各种莫名其妙的coredump问题。ZendAPI几乎没有文档,开发者要想真正掌握这项技能,需要付出大量的学习时间。以上是swoole插件开发者的心声。可见,使用这种方式开发插件,对于我们初学者的自信心是一种严重的打击。幸运的是,一些大神已经为我们开发php扩展准备了其他的方法。你不需要学习zendapi,也不需要精通c语言,照样可以开发php扩展,而且生成的扩展运行速度不会和c语言开发相差太多。2、使用zephir类PHP语言开发Zephir提供了一种类似于PHP的高级语言语法来自动生成扩展的C语言代码,使得编写PHP扩展变得非常简单。但是这种开发方式带来了一个问题,就是因为他没有使用c/c++语言开发,所以没有办法直接使用现有的各种c/c++开发库来实现强大的功能。所以感觉有点鸡肋。3、使用PHP-XC++语言开发php-x是知名swoole扩展开发者根据多年开发经验提炼出来的一套基于C++的扩展开发框架。从文档来看,这是一个比较好用的开发框架,数据类型齐全,和phpcpp的开发风格很像,不过我还没有尝试过。根据php-x官方文档,开发的扩展只支持PHP7及以上版本,有点遗憾。4、使用phpcppC++语言开发PHPCPP是我推荐的PHP扩展开发框架,简洁易懂,功能强大,开发效率高,代码易于维护,执行速度快。PHPCPP是一个免费的php开发扩展库,主要针对C++语言,可以扩展和构建类集合。它使用简单的计算机语言使扩展更加有趣和有用。方便开发者维护编写,简单易用。易于理解和维护,代码美观。用C++编写的算法看起来与用PHP编写的算法几乎相同。如果您知道如何使用PHP进行编程,那么您可以轻松地学习如何使用C++进行同样的操作。优势一:无需Zend引擎知识。ZendEngine的内部结构过于复杂,ZendEngine的代码很乱,而且大多没有文档记录。但是PHP-CPP库已经将所有这些复杂的结构封装在非常易于使用的C++类和对象中。您可以用C++编写速度惊人的算法,而无需直接调用ZendEngine,甚至无需查看ZendEngine源代码。使用PHP-CPP,您可以编写本机代码而无需处理PHP的内部结构。优势二:支持所有重要的PHP函数使用PHP-CPP,您可以像使用普通PHP脚本一样轻松处理变量、数组、函数、对象、类、接口、异常和命名空间。除此之外,您还可以使用C++的所有功能,包括线程、lambda和异步编程。优势三:支持PHP5.X和PHP7的扩展开发PHP-CPP有两套扩展开发框架,分别支持PHP5.X和PHP7。虽然是两个框架代码,但是接口是一样的。所以如果你想开发兼容多个版本的php扩展,做兼容不会花费你太多额外的时间。五、各开发框架的helloworldextension源码对比下面列出了各框架的helloworldextension源码。从源码的长度和复杂程度可以有一个直观的感受。ext-skel生成的C扩展源码显然可读性极差,极难理解。zephir的扩展源码最接近PHP语法,最容易上手,但很难加入成熟的c/c++库代码。PHP-X和PHPCPP的源码风格非常相似,都是标准的C++语言,通俗易懂。不难想象,这两种开发扩展的方式一定是最合适的,因为我们不仅可以使用C++封装来简化开发,还可以直接调用市面上各种成熟的C++库来为我们服务。ext-skel的helloworld源代码#ifdefHAVE_CONFIG_H#include"config.h"#endif#include"php.h"#include"php_ini.h"#include"ext/standard/info.h"#include"php_helloworld.h""staticintle_helloworld;PHP_FUNCTION(confirm_helloworld_compiled){char*arg=NULL;intarg_len,len;字符*字符串;如果(zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC,"s",&arg,&arg_len)==FAILURE){return;}len=spprintf(&strg,0,"恭喜!您已成功修改ext/%.78s/config.m4。模块%.78s现在已编译到PHP中。","helloworld",arg);RETURN_STRINGL(strg,len,0);}PHP_MINIT_FUNCTION(helloworld){返回成功;}PHP_MSHUTDOWN_FUNCTION(helloworld){返回成功;}PHP_RINIT_FUNCTION(helloworld){返回成功;}PHP_RSHUTDOWN_FUNCTION(helloworld){返回成功;}PHP_MINFO_FUNCTION(helloworld){php_info_print_table_start();php_info_print_table_header(2,"helloworldsupport","enabled");php_info_print_table_end();}constzend_function_entryhelloworld_functions[]={PHP_FE(confirm_helloworld_compiled,NULL)/*用于测试,稍后删除。*/PHP_FE_END/*必须是helloworld_functions[]*/zend_module_entry中的最后一行如果在请求开始时无事可做*/PHP_RSHUTDOWN(helloworld),/*如果在请求结束时无事可做,则替换为NULL*/PHP_MINFO(helloworld),PHP_HELLOWORLD_VERSION,STANDARD_MODULE_PROPERTIES};#ifdefCOMPILE_DL_HELLOWORLDZEND_GET_MODULE(helloworld)#endifzephir的你好世界源代码命名空间测试;classHello{publicfunctionsay(){echo"HelloWorld!";}}PHP-X的helloworld源码#includeusingnamespacestd;usingnamespacephp;//声明函数PHPX_FUNCTION(say_hello);//导出模块PHPX_EXTENSION(){Extension*ext=newExtension("hello-world","0.0.1");ext->registerFunction(PHPX_FN(say_hello));returnext;}//实现函数PHPX_FUNCTION(say_hello){echo("helloworld");}PHPCPPhelloworld源码#includevoidsay_hello(Php::Parameters¶ms){php::out<<"helloworld"<