php extension devlop - yaokun123/php-wiki GitHub Wiki

PHP扩展开发

一、为什么要开发PHP扩展

PHP有丰富的函数库,一般情况下已经足够我们使用。为什么还要开发PHP扩展呢?主要有以下几个原因:

如果应用是非常注重效率的,如复杂的图像算法,需要编写成PHP扩展。

有些系统调用不能用PHP直接访问,需要编写成扩展,例如使用Linux下的fork()函数创建一个进程。

如果想商业化一个应用,但是又不想暴露源代码,可以编写成扩展(当然还可以使用Zend公司的加密工具Zend Guard)

二、搭建PHP扩展框架

2.1、PHP源代码目录

目录 描述
ext 这是存放动态和内建模块的目录,在这里可以找到所有PHP官方扩展,并且以后也会在这里编写扩展
main 包含PHP主要宏定义
pear 该目录就是“PHP扩展与应用库”目录,包含PEAR核心文件
sapi 包含不同服务器抽象层的代码
TSRM Zend和PHP的“线程安全资源管理器”目录
Zend 包含Zend引擎的所有文件。在这里你可以找到所有Zzend API定义个宏等

除了以上源码目录之外,还需要了解以下几个重要的头文件,因为在编写扩展的过程中,一般要把这些文件包含进来:

main/php.h:位于main目录下。包含绝大部分PHP宏及PHP API定义

Zend/zend.h:位于Zend目录下。包含绝大部分Zend宏及Zend API定义

Zend/zend_API.h:位于Zend目录下。包含Zend API定义

2.2ext_skel工具

PHP内核开发人员为编写PHP扩展提供一个很好用的“自动构建系统”工具“ext_skel”。使用ext_skel可以很方便地搭建一个扩展框架。

ext_skel工具在PHP源码目录下的ext目录下。ext目录下有两个文件,ext_skel和ext_skel_win32.php,第一个在linux系统下使用,而ext_skel_win32.php则是在wiundows系统下使用的。

2.3Windows平台环境配置

在Windows平台配置编写PHP扩展的环境比较简单,只需要安装VC++就行了,版本建议使用6.0,因为vc++6.0速度比较快,而且比较轻巧。另外建议安装"Visual Assist X",这样会使编写PHP扩展变得非常容易。 除了安装VC++之外,还需要一样非常重要的东西,那就是PHP源代码。

1、使用ext_skel工具 使用ext_skel工具创建出一个PHP扩展的框架,首先在命令行下进入到PHP源代码目录的ext目录下,输入以下命令创建扩展框架

php ext_skel_win32.php --extname = myext

成功之后会发现ext目录下多了一个myext目录,目录中myext.dsp是VC++的工程文件

2、编译安装扩展 用vc++打开myext.dsp工程文件,按编译按钮开始编译这个扩展。在编译的过程中,会发现编译出错了,错误提示找不到php5ts.lib文件。从PHP的安装目录(注意不是源代码目录)下的dev目录中,把php5ts.lib文件复制到创建的扩展目录(myext)下,然后再次按编译按钮,这次成功安装扩展

编译扩展之后,源代码的根目录下多了一个Release_TS目录,在该目录中有刚刚编译好的动态扩展文件php_myext.dll

注意:如果在源代码根目录下找不到Release_TS目录,而找到Debug_TS目录的话,请把VC++的编译模式改为Release。

至此,已经在Windows环境上创建一个PHP扩展,现在把这个扩展安装到PHP中。

安装也很简单,只要把编译好的dll文件复制到php安装目录下的ext目录下,然后在php.ini配置文件中添加"extension=php_myext.dll",并重启Web服务器就可以。

可以调用confirm_myext_compiled()函数测试我们的扩展

<?php
    confirm_myext_compiled("hello myext");

2.4Linux平台环境配置

1、安装php-dev包 使用php-dev包中的phpize工具可以减少很多繁琐的步骤。如果使用PHP源码编译的话,就不用安装php-dev包,因为PHP源码中已经有phpize工具

2、使用ext_skel工具

./ext_skel --extname = myext

生成框架后,需要修改扩展m4文件。打开config.m4文件,去掉以下配置前的dnl:

dnl PHP_ARG_ENABLE(hello,whether to enable hello support,
dnl [--enable-hello  Enable hello support]

修改为:

PHP_ARG_ENABLE(hello,whether to enable hello support,
[--enable-hello  Enable hello support]


vim php_extname.h文件

搜索:extern zend_module_entry 新增一行:
PHP_FUNCTION(yaok_test);//yaok_test就是新增的函数定义


vi extname.c
搜索:const zend_function_entry extname_functions[] 新增一行:
PHP_FE(yaok_test, NULL)//yaok_test就是新增的函数定义


在 extname.c 底部新增一个方法
PHP_FUNCTION(yaok_test)
{
    char *arg = NULL;
    int arg_len, len;
    char *strg;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
        return;
    }
    len = spprintf(&strg, 0, "Hello World: %s", arg);
    RETURN_STRINGL(strg, len, 0);
}

3、编译安装扩展 创建好扩展框架后,进入到扩展的目录下,使用phpize命令生成扩展的配置工具,然后编译和安装

cd myext
phpsize
./configure --with-php-config=/usr/local/php5/bin/php-config
make && make install

编译安装后,可以在/usr/localphp5/lib/extension/no-debug-non-zts-20060613/目录下看到生成的扩展文件myext.so,接着在php.ini文件中添加扩展信息: extension=myext.so 最后使用php -m命令查看扩展是否安装成功。

几个成熟的扩展

1、Yaf-一个PHP扩展实现的PHP框架

具体的可以参看

Github地址

PECL地址

以及一个中文版的手册

2、Plua进入Pecl------支持在PHP中调用Lua脚本

3、随着PHP7.4而来的有一个我认为非常有用的一个扩展:PHP FFI(Foreign Function interface)FFI提供了高级语言直接的互相调用,而对于PHP来说,FFI让我们可以方便的调用C语言写的各种库。