如何开发pHp扩展离我们并不远?|?

2023-10-31    分类: 网站建设

原站地址:%E6%89%A9%E5%b1%95%E5%bC%80%E5%8F%91%E5%8F%8A%E5%85%A5%E9%97%A8%E8%A7 %A3%E6%83%91/

说在最前线

作为一个pHp程序员,如果不了解pHp内核和pHp扩展开发,那似乎是一件很“丢人”的事情,嗯,真的很“丢人”!虽然接触pHp已经三年多了,但一直没有机会,也没有主动学习过,所以更觉得“丢脸”。这种情况下,如果面试官问你有没有因为长期接触pHp而学习了pHp的底层知识,如果你理解了php 扩展开发,你会更“丢脸”。所以,废话不多说,是时候进行 pHp 扩展了。

什么是 pHp 扩展?

大家在日常的开发过程中或多或少都接触过pHp扩展,比如可以查看的vld扩展,比如性能分析工具,而我们经常使用的pDO其实就是作为扩展运行在pHp中的(只是pDO已经默认编译进了pHp源代码中,所以我们不需要单独安装),所以pHp扩展离我们不远了。

为什么要开发 pHp 扩展?

基础知识

准备好工作了

操作系统:.5(只要是)

pHp版本:pHp5.6.9(最好在pHp5.3之后,pHp7之前,毕竟pHp7对内核做了很多改动)

注:我这里的php环境是lnmp一键安装包搭建的,lnmp一键安装的入口在这里

第一个扩展名为

不要担心这里的概念,让我们快速浏览一下,了解扩展通常是如何播放的。

1. 通过pHp提供的工具生成扩展的骨架,--扩展名在右边

~/software/lnmp1.2-full/src/php-5.6.9/ext  ᐅ pwd
/root/software/lnmp1.2-full/src/php-5.6.9/ext
~/software/lnmp1.2-full/src/php-5.6.9/ext  ᐅ ./ext_skel --extname=myfirstext
Creating directory myfirstext
Creating basic files: config.m4 config.w32 .gitignore myfirstext.c php_myfirstext.h CREDITS EXpERIMENTAL tests/001.phpt myfirstext.php [done].
To use your new extension, you will have to execute the following steps:
1.  $ cd ..
2.  $ vi ext/myfirstext/config.m4
3.  $ ./buildconf
4.  $ ./configure --[with|enable]-myfirstext
5.  $ make
6.  $ ./sapi/cli/php -f ext/myfirstext/myfirstext.php
7.  $ vi ext/myfirstext/myfirstext.c
8.  $ make
Repeat steps 3-6 until you are satisfied with ext/myfirstext/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.

2. 进入目录,修改.m4文件,删除下面代码前面的dnl,我知道你不想知道这个dnl是干什么的,但是我还是想说这个dnl是只是一个评论,编辑它,退出!

dnl pHp_ARG_ENAbLE(myfirstext, whether to enable myfirstext support,
dnl Make sure that the comment is aligned:
dnl [  --enable-myfirstext           Enable myfirstext support])

这时候可以执行ls看看一般都有哪些文件。让我先告诉你。比较重要的是.c、.h和.php,最重要的是.c,文件夹也是,以后我们的测试脚本都会写在这里。

~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ ls
config.m4   CREDITS       myfirstext.c    php_myfirstext.h
config.w32  EXpERIMENTAL  myfirstext.php  tests

3.登场,会根据我们的.m4配置生成一些编译好的文件(比如etc)。

注:由于我这里是为php5.6.9开发扩展,所以尽量使用php5.6.9源码,如果你用我的pHp版本是不同,那么你可以在你的pHp源码包中找到该命令并执行它。

~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ ../../scripts/phpize 
Configuring for:
pHp Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ ls
acinclude.m4    config.guess  configure     EXpERIMENTAL     missing         php_myfirstext.h
aclocal.m4      config.h.in   configure.in  install-sh       mkinstalldirs   run-tests.php
autom4te.cache  config.m4     config.w32    ltmain.sh        myfirstext.c    tests
build           config.sub    CREDITS       Makefile.global  myfirstext.php

执行后,发现了很多文件。

4.编译安装三连发

~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ ./configure
~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ make
~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ make install
Installing shared extensions:     /usr/lib64/php/modules/

注意:如果编译安装顺利,则忽略这个

./报告re2c错误:执行yum -y re2c

使错误(/root//.2-full/src/php-5.6.9/ext//.c:146:错误:``未声明(不在功能中)):打开。 c、删除第146行,替换为{NULL, NULL, NULL}。

5.恭喜你,你的第一个扩展开发成功了,就是名字不太好听,现在我们验证一下我们的扩展是否可用

在 CLI 模式下找到你的 php.ini(执行命令 php -i | grep php.ini 找到它,添加一行

extension=myfirstext.so

重启php,我这里重启php-fpm。执行命令看到如下,证明你的第一个扩展可以正常工作了!可以看出我们通过扩展创建了一个新的pHp函数()。

~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ php -r 'echo confirm_myfirstext_compiled("Hello World!");' 
Congratulations! You have successfully modified ext/myfirstext/config.m4. Module Hello World! is now compiled into pHp.

问题来了?

好了,既然来到了这里,我想你的第一个 pHp 扩展也已经开发出来了。在上面的例子中,我们新建了一个pHp内置函数(),并通过它实现了一个简单的函数。是不是有点不上瘾?不知道你是不是太沉迷了,我相当沉迷,但是我对我刚刚开发的第一个扩展仍然有很多疑问。下面我们将逐步解读这些我们都有的疑问。

扩展文件夹中的文件是做什么用的?

在这里,我们将只关注少数文件,因为大多数文件都是由该工具自动生成的。在这里,我将对这些文件进行分类。

代码文件:

。H

。C

至于为什么会有.h文件,我想你知道。

扩展配置文件:

.m4: *在 nix 下使用

.w32:用于

我现在将跳过其他文件,因为我不知道。

最重要的 .c 文件在哪里重要?

首先我们把.c文件分块,这样更直观(因为里面满是注释,这里没有列出注释部分)

/**
 * 头文件部分
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_myfirstext.h"
static int le_myfirstext;
/**
 * 自定义函数部分,看到该函数的参数还熟吗?这里就是我们上面自定义函数的实现部分!
 */
pHp_FUNCTION(confirm_myfirstext_compiled)
{
    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, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now        compiled into pHp.", "myfirstext", arg);
    RETURN_STRINGL(strg, len, 0);
}
/**
 * Module初始化和Shutdown部分
 */
pHp_MINIT_FUNCTION(myfirstext)
{   
    return SUCCESS;
}
pHp_MSHUTDOWN_FUNCTION(myfirstext)
{   
    return SUCCESS;
}
/**
 * Request初始化和shutdown部分
 */
pHp_RINIT_FUNCTION(myfirstext)
{
    return SUCCESS;
}
pHp_RSHUTDOWN_FUNCTION(myfirstext)
{   
    return SUCCESS;
}
/**
 * Module Info部分,这里主要控制将扩展信息打印到phpinfo()中
 */
pHp_MINFO_FUNCTION(myfirstext)
{
    php_info_print_table_start();
    php_info_print_table_header(2, "myfirstext support", "enabled");
    php_info_print_table_end();
    /* Remove comments if you have entries in php.ini
    DISpLAY_INI_ENTRIES();
    */
}
/**
 * function_entry部分,这里主要对我们前面自定义的confirm_myfirstext_compiled函数做一个封装
 */
const zend_function_entry myfirstext_functions[] = {
    pHp_FE(confirm_myfirstext_compiled, NULL)       /* For testing, remove later. */
    {NULL, NULL, NULL}
        /* Must be the last line in myfirstext_functions[] */
};
/**
 * module_entry部分,这里应该算是整个文件最重要的部分了吧,属于我们扩展的CpU,这里将会告诉pHp如何初始化我们的扩展。
 */
zend_module_entry myfirstext_module_entry = {
    STANDARD_MODULE_HEADER,
    "myfirstext",
    myfirstext_functions,
    pHp_MINIT(myfirstext),
    pHp_MSHUTDOWN(myfirstext),
    pHp_RINIT(myfirstext),      /* Replace with NULL if there's nothing to do at request start */
    pHp_RSHUTDOWN(myfirstext),  /* Replace with NULL if there's nothing to do at request end */
    pHp_MINFO(myfirstext),
    pHp_MYFIRSTEXT_VERSION,
    STANDARD_MODULE_pROpERTIES
};
#ifdef COMpILE_DL_MYFIRSTEXT
ZEND_GET_MODULE(myfirstext)
#endif

所以,.c中最重要、最基本的代码段是这样的。

让我们创建一个新函数,称为 ()

只需要两步就可以实现我们想要的功能。

1.添加函数定义

......
pHp_FUNCTION(confirm_myfirstext_compiled)
{
    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, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now        compiled into pHp.", "myfirstext", arg);
    RETURN_STRINGL(strg, len, 0);
}
pHp_FUNCTION(hello_world)
{   
    php_printf("hello world!");
}
......

2.添加功能

const zend_function_entry myfirstext_functions[] = {
    pHp_FE(confirm_myfirstext_compiled, NULL)       /* For testing, remove later. */
    pHp_FE(hello_world, NULL)
    {NULL, NULL, NULL}
        /* Must be the last line in myfirstext_functions[] */
};
c
好,再一次编译安装三连发,重启pHp
```bash
~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ make install
Installing shared extensions:     /usr/lib64/php/modules/
~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ service php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
~/software/lnmp1.2-full/src/php-5.6.9/ext/myfirstext  ᐅ php -r "hello_world();"
hello world!

当然,我们直接通过上面pHp官方提供的工具创建了扩展骨架,其实我们也可以手动创建。

手工制作这里就不赘述了,大家可以直接跳到学习walu大神的开源项目walu/,在这里系统学习。这几天一直在研究这个教程,也有幸得到了瓦鲁大神的帮助。

那么php 扩展开发,我该如何阅读本教程?我会在这里做一个小分享

首先,请打开目录。您会发现目前总共有 20 章。这些天我已经学习了前13章和18章。保证的是所有的例子都可以验证。不仅有利于开发方法的扩展和pHp内核知识的增长,所以推荐墙!

如果觉得看walu大神的教程有点难,可以看我的博客pHp扩展开发相关内核

这个其实是我在学习过程中整理出来的,不保证对你有用。

如果你想得到原版,你可以点击这里/

网页标题:如何开发pHp扩展离我们并不远?|?
分享URL:/news33/291783.html

成都网站建设公司_创新互联,为您提供网站导航网站营销网站排名做网站营销型网站建设网站设计公司

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都seo排名网站优化