PHP 扩展开发初探 php7扩展开发
bigegpt 2024-10-12 07:00 26 浏览
什么是 PHP 扩展
通俗说,PHP 扩展是增强 PHP 语言功能的插件。PHP 提供了编程语言的语法,比如分支、循环、函数、类等,这些是 PHP 本身所提供的。在某些情况下需要在 PHP 语言的基础上进行扩展,那么就需要通过 PHP 底层提供的数据结构和接口来开发 PHP 扩展,从而来补充或扩展 PHP 语言,使之更加的强大。当然了,PHP 本身就已经集成了一些基本的、强大的、优秀的 PHP 扩展。
PHP 扩展的好处
从上面的了解得知,PHP 扩展可以在 PHP 原有的基础上来扩展 PHP 的功能,使之更为的强大。另一方面,PHP 扩展可以通过“插件式”的方式来管理和维护 PHP 的功能,如果将全部的功能整合到 PHP 语言中,PHP 想必会过于臃肿,且又不够灵活。而有了扩展,就解决了这样的问题。
PHP 扩展的存在形式
在 Linux 系统下,PHP 扩展以 .so 文件存在,在 Windows 下以 .dll 文件存在。
什么时候使用 PHP 扩展
单独的使用 PHP 语言并不能满足所有的开发,比如在项目中使用 Redis 或 MongoDB 时,就需要相应的 PHP 扩展,来增强 PHP 语言,让 PHP 可以来操作 Redis 或者 MongoDB,以完成更加功能强大的项目。
什么时候开发自己的 PHP 扩展
开发自己的 PHP 扩展是必须的么?其实不是。通常情况下,作为一个 PHPer 是不需要自己开发 PHP 扩展的,但是某些情况下可能是必须要开发 PHP 扩展的。比如,我就遇到了这样的问题。合作的第三方提供了 Windows 下的动态链接库文件(.dll 文件,非 COM 的 DLL 文件),而我又没有找到如何在 PHP 下加载调用 DLL 文件的方式,因此我需要写 PHP 扩展,通过 PHP 的扩展来加载和调用第三方提供的 DLL 文件。
开发自己的 PHP 扩展
在前面我已经提到了我遇到的问题,合作的第三方提供了 Windows 下的动态链接库文件,而我又没有找到 PHP 下加载和调用 DLL 文件的方式,因此决定自己编写 PHP 扩展来加载和调用第三方提供的 DLL 文件中的导出函数。以下,就是我对于搭建开发 PHP 扩展环境和编译 PHP 扩展源码的记录。
准备工具
首先说明一点,DLL 文件只能在 Windows 系统上运行,Linux 系统上是无法进行运行的。那么,我们这个扩展是不考虑 Linux 系统的,只考虑 Windows 系统即可。因此,准备的开发工具是 VS2015。起初,我在网上查找了一些资料,很多资料中都写到,在 Windows 下开发 PHP 扩展需要安装 CygWin,经过我自己的学习,可以告诉大家“不需要”。当然了,我们的扩展只在 Windows 系统上运行,如果需要在 Linux 系统上运行,是否需要 Cygwin 我就不得而知了。当然了,其他版本的 VS 也应该是可以的,只是我只测试了 VS2015 罢了。
下载 PHP 的源代码
除了需要安装 VS2015 以外,还需要下载 PHP 的源码,我下载的源码是 PHP 7.2 的源码。
下载 PHP 源码的地址是:https://windows.php.net/download/
打开该地址后,下载如下图所示的源代码:
在这里,下载 PHP 7.2 的源码,并注意在源码下面有一个 VC15 x64 的字样。
下载完的的文件为:php-7.2.20-src.zip
下载完源码进行解压,解压后的目录为:php-7.2.20-src
下载源码并不是一件复杂的事情,但是页面中有多个版本的源码可供下载,选择哪个有时也是比较纠结的问题,这里就下载 php7.2 的源码,因为我本地使用的就是 php7.2 的环境。
创建扩展
进入 php-7.2.20-src\ext 目录下,在该目录下有一个名为 ext_skel_win32.php 的文件,在命令行中执行:
php ext_skel_win32.php --extname=loaddll
其中,loaddll 是要创建的扩展的名称。想要成功执行该命令,需要将 PHP 的可执行程序添加到环境变量中。
执行情况如下:
λ php ext_skel_win32.php --extname=loaddll
Creating directory loaddll
FIND: Parameter format not correct
chmod: missing operand after ‘644’
Try 'chmod --help' for more information.
FIND: Parameter format not correct
chmod: missing operand after ‘755’
Try 'chmod --help' for more information.
Creating basic files: config.m4 config.w32 .gitignore loaddll.c php_loaddll.h CREDITS EXPERIMENTAL tests/001.phpt loaddll.php [done].
To use your new extension, you will have to execute the following steps:
1. $ cd ..
2. $ vi ext/loaddll/config.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-loaddll
5. $ make
6. $ ./sapi/cli/php -f ext/loaddll/loaddll.php
7. $ vi ext/loaddll/loaddll.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/loaddll/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
看到如上的输出提示,则说明我们创建的 PHP 扩展生成成功了。以上输出如下所示:
此时,在 \ext 目录下生成了 loaddll 的目录,该目录是生成出的 PHP 的扩展模板,可以在模板的基础上进行开发。
使用 VS2015 创建扩展项目
打开 VS2015,我这里使用的是 VS2015,其他开发环境没有进行测试。
在 VS2015 中选择 “文件” -> “新建” -> “从现有代码创建项目”,来创建 PHP 扩展的解决方案,如下图:
选择了 “从现有代码创建项目” 后,会出现创建项目的向导,如下图:
直接点击 “下一步”,到如下图:
在此步骤,选择刚才生成的扩展模板的目录,然后填入项目名称,这里是“loaddll”,点击“下一步”,到达如下图:
此步骤选择DLL项目,点击下一步,到达如下图:
直接点击“下一步”,到达如下图:
点击“完成”,等待 VS2015 开始创建项目。
配置编译选项并编译项目
在 VS2015 生成项目完毕后,切换项目为 “Release”和“x64”的选项,如下图:
切换完成后,在项目上右键选择“属性”,如下图:
修改配置类型为 DLL,这样生成的目标文件扩展名自动变为 .dll,如下图所示:
选择“配置属性” -> “C/C++” -> “常规”,在“附加包含目录”中点击“编辑”来添加相关的目录,如下图:
这里需要包含的目录包括如下图的几个目录:
这里主要是添加了 PHP 源码的几个目录,因为编译 PHP 扩展的源码时需要 PHP 的底层内核数据结构进行支持,因此需要包含以上的目录。
选择“配置属性” -> “C/C++” -> “预处理器”,在“预处理器定义”中点击“编辑”来添加相关预处理指令,如下图:
在预处理中,HAVE_LOADDLL 中的 LOADDLL 是扩展的名称,COMPILE_DL_LOADDLL 中的 LOADDLL 同样也是扩展的名称,这个名称与最开始生成扩展模板时的名称应该一致。
编译源代码
把 php-7.2.20-src\win32\build\ 目录下的 config.w32.h.in 复制到 php-7.2.20-src\main\ 目录下,并重命名为 config.w32.h,这个 .h 文件在编译时是需要的,但是在 php-7.2.20-src\main\ 下并没有该文件,因此需要自己手动进行复制。
在 config.w32.h 中增加如下代码
#define PHP_COMPILER_ID "VC15"
注意这里的 VC15 ,在下载源代码的时候,我们已经见到过这个标识了。
接着,从 PHP 的安装目录中复制 php7ts.lib 文件到 loaddll 目录下,注意,是从PHP 的安装目录中,而不是 PHP 源代码的目录中。
php7ts.lib 在目录 php7.2.10\dev 目录下,我使用的是 wamp64 下的 php7.2.10,大家自己使用对应的 .lib 文件即可,当然,这个 .lib 文件也必须是 php7.2 的,因为我们下载的是 php7.2 的源码。
在项目的 resource Files 下添加 php7ts.lib 文件,添加该文件就比较简单了,同样是右键添加即可。
按下 F7 生成解决方案,如图:
看到“成功 1 个”文件以后,在目录 \php-7.2.20-src\ext\loaddll\x64\Release 下会生成一个 loaddll.dll 文件,这个文件就是我们的 PHP 扩展文件。
PHP 扩展的安装与测试
将VS2015 生成 loaddll.dll 重命名为 php_loaddll.dll ,将其拷贝到 PHP 环境的扩展中,我的路径是 php\php7.2.10\ext,想必熟悉 PHP 的应该都会添加 PHP 扩展。如下图:
在 php.ini 文件中增加配置,如下图:
使用 php -m 来查看是否有 loaddll.dll 模块,如下图:
phpinfo 查看,如下图:
通过上面可以看出,我们的 PHP 扩展已经正常安装了,接下来就需要测试我们的扩展是否可以运行了。
在 PHP 源码目录下 php-7.2.20-src\ext\loaddll\ 有一个 loaddll.php 的测试文件,在命令行下进行执行该命令:
php loaddll.php
输出内容如下:
λ php loaddll.php
Functions available in the test extension:
confirm_loaddll_compiled
Congratulations! You have successfully modified ext/loaddll/config.m4. Module loaddll is now compiled into PHP.
如下图:
看到如上输出,说明该扩展的模板编译成功,可以继续开发实际的扩展模块了。
总结
很多时候,学习编程的第一步就是搭建环境,而往往搭建环境的过程中由于步骤过于复杂,而资料又没有傻瓜化的详细步骤,导致很多想要学习或入门的程序员连第一步都无法踏出。对于开发 PHP 扩展而言也是一样的。
如何通过 PHP 扩展来让 PHP 程序可以直接调用 DLL 中的函数,除了需要掌握 C 语言的知识以外,还需要掌握 Windows 程序设计的知识,本文就不再讨论了,因为有 C 语言的知识和 Windows 程序设计的知识,在 PHP 扩展中调用 DLL 并非难事。
希望本文对大家有所帮助!
相关推荐
- 当Frida来“敲”门(frida是什么)
-
0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...
- 服务端性能测试实战3-性能测试脚本开发
-
前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...
- Springboot整合Apache Ftpserver拓展功能及业务讲解(三)
-
今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...
- Linux和Windows下:Python Crypto模块安装方式区别
-
一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...
- Python 3 加密简介(python des加密解密)
-
Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...
- 怎样从零开始编译一个魔兽世界开源服务端Windows
-
第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...
- 附1-Conda部署安装及基本使用(conda安装教程)
-
Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...
- 如何配置全世界最小的 MySQL 服务器
-
配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...
- 如何使用Github Action来自动化编译PolarDB-PG数据库
-
随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...
- 面向NDK开发者的Android 7.0变更(ndk android.mk)
-
订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...
- 信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要
-
问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...
- OpenSSH 安全漏洞,修补操作一手掌握
-
1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...
- Linux:lsof命令详解(linux lsof命令详解)
-
介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...
- 幻隐说固态第一期:固态硬盘接口类别
-
前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...
- 新品轰炸 影驰SSD多款产品登Computex
-
分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...
- 一周热门
- 最近发表
-
- 当Frida来“敲”门(frida是什么)
- 服务端性能测试实战3-性能测试脚本开发
- Springboot整合Apache Ftpserver拓展功能及业务讲解(三)
- Linux和Windows下:Python Crypto模块安装方式区别
- Python 3 加密简介(python des加密解密)
- 怎样从零开始编译一个魔兽世界开源服务端Windows
- 附1-Conda部署安装及基本使用(conda安装教程)
- 如何配置全世界最小的 MySQL 服务器
- 如何使用Github Action来自动化编译PolarDB-PG数据库
- 面向NDK开发者的Android 7.0变更(ndk android.mk)
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)