编写自己的php扩展函数


Posted in PHP onOctober 09, 2006

编写自己的php扩展函数 php程序写的时间长了,自然对他所提供的功能了如指掌,他所提供的一大堆功能,真是觉得很好用,但有时候会发现php也缺少一些功能,自己总是会产生为php添加一些自定义的功能的想法。久而久之,终于今天憋不住了,开始动手研究如何添加。

  

下载一个php的源代码包,这里使用的是php 4.0.5版,解压后会看到php的根目录下会有README.EXT_SKEL这样一个文件,打开详细阅读了一下,发现了一个非常好用的工具,这个工具可以帮你构建一个空的php扩展,然后你向里面添加相应的代码就可以完成你自己的功能扩展了。下面我们就来介绍如何使用这个工具。

  

首先转移你的目录到php的目录下的ext目录,如果你只需要一个基本的扩展框架的话,执行下面的命令:

./ext_skel --extname=module_name

module_name是你自己可以选择的扩展模块的名字,例如我选择的my_module。执行工具后会自动在ext目录下建立你选择的module_name名字的目录,里面已经生成了相关的代码,这些代码中只需要调整config.m4文件中的三行注释就可以正常的编译带这个自定义扩展模块的php了。在php的根目录执行下列操作就可以得到。

./buildconf

./configure --enable-module_name

make

  

下面我来演示建立my_module扩展框架的全过程,为了更有效果,我们来完成一个php的扩展功能,在php中调用这个功能可以在web页面中显示hello world这个经典单词。

在php目录下的ext目录中,执行下面的命令

./ext_skel --extname=my_module

得到反馈结果:

Creating directory my_module

Creating basic files: config.m4 Makefile.in .cvsignore my_module.c php_my_module.h tests/001.phpt my_module.php [done].

  

To use your new extension, you will have to execute the following steps:

1.  $ cd ..

2.  $ vi ext/my_module/config.m4

3.  $ ./buildconf

4.  $ ./configure --[with|enable]-my_module

5.  $ make

6.  $ ./php -f ext/my_module/my_module.php

7.  $ vi ext/my_module/my_module.c

8.  $ make

  

Repeat steps 3-6 until you are satisfied with ext/my_module/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.

  

如果你能看懂上面的东西,那就照着去做。如果不是太明白的话,按照我下面的提示来做也可以。

Cd my_module

首先进入my_module目录

vi config.m4

使用文本编辑器打开config.m4文件,文件内容大致如下:

dnl $Id$

dnl config.m4 for extension my_module

dnl don't forget to call PHP_EXTENSION(my_module)

  

dnl Comments in this file start with the string 'dnl'.

dnl Remove where necessary. This file will not work

dnl without editing.

  

dnl If your extension references something external, use with:

  

dnl PHP_ARG_WITH(my_module, for my_module support,

dnl Make sure that the comment is aligned:

dnl [  --with-my_module             Include my_module support])

  

dnl Otherwise use enable:

  

dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,

dnl Make sure that the comment is aligned:

dnl [  --enable-my_module           Enable my_module support])

  

if test "$PHP_MY_MODULE" != "no"; then

  dnl If you will not be testing anything external, like existence of

  dnl headers, libraries or functions in them, just uncomment the

  dnl following line and you are ready to go.

  dnl Write more examples of tests here...

  PHP_EXTENSION(my_module, $ext_shared)

Fi

  

根据你自己的选择将

dnl PHP_ARG_WITH(my_module, for my_module support,

dnl Make sure that the comment is aligned:

dnl [  --with-my_module             Include my_module support])

修改成

PHP_ARG_WITH(my_module, for my_module support,

Make sure that the comment is aligned:

[  --with-my_module             Include my_module support])

或者将

dnl PHP_ARG_ENABLE(my_module, whether to enable my_module support,

dnl Make sure that the comment is aligned:

dnl [  --enable-my_module           Enable my_module support])

修改成

PHP_ARG_ENABLE(my_module, whether to enable my_module support,

Make sure that the comment is aligned:

[  --enable-my_module           Enable my_module support])

  

一般我会选择后者,然后保存退出。如果你对vi文本编辑器的操作有困难的话,请参考相应的说明文章,这里就不再详细描述了。

Vi my_module.c

将文件其中的下列代码进行修改

/* Every user visible function must have an entry in my_module_functions[].

*/

function_entry my_module_functions[] = {

        PHP_FE(say_hello,       NULL)  /* ß添加着一行代码 */

        PHP_FE(confirm_my_module_compiled,      NULL) /* For testing, remove later. */

        {NULL, NULL, NULL}      /* Must be the last line in my_module_functions[] */

};

  

在文件的最后添加下列代码

PHP_FUNCTION(say_hello)

{

        zend_printf("hello world\n");

}

保存文件退出

  

vi php_my_module.h

在文件中PHP_FUNCTION(confirm_my_module_compiled);一行前面添加下面的代码

PHP_FUNCTION(say_hello);

保存文件退出

  

退回到php的根目录下,执行下面的命令

./buildconf

./configure --enable-my_module

make

  

如果一切顺利的话,我们现在已经将扩展模块my_module编译到php里面了。我们编写下面的代码进行测试

<?

       Say_hello();

?>

保存文件为say_hello.php

在php的根目录下运行

./php ?q say_hello.php

正常情况下会显示

hello world

表示我们的第一个扩展正常的运行了!

  

解释一下上面做的操作,ext_skel生成一些框下文件,我们需要修改以下文件

my_module.c  扩展模块的主程序

php_my_module.h 扩展模块的头文件

config.m4  配置文件

  

主程序中描述了php扩展模块的声明,模块中含有多少个函数,各个函数的作用,在phpinfo函数中显示什么内容,模块初始化做些什么,结束做些什么都会在这个文件里进行描述。我们在上面只是添加了一个函数say_hello,并且描述了say_hello函数的具体内容,调用zend_printf系统函数在php中打印字符串。

  

在对应的头文件中声明了say_hello这个函数,从而完成了我们预期的功能。下面我们会编写一个更复杂的扩展,创造一个带参数的php扩展函数,根据给入的参数,显示hello world, xxxx。Xxxx代表输入的字符串内容,例如我的名字yorgo。

  

Vi my_module.c

修改最后的say_hello函数内容如下:

PHP_FUNCTION(say_hello)

{

        zval **yourname;

  

        if (ZEND_NUM_ARGS() != 1
zend_get_parameters_ex(1, &yourname) == FAILURE)

        {

                WRONG_PARAM_COUNT;

        }

  

        zend_printf("hello world, %s\n", Z_STRVAL_PP(yourname));

}

存盘退出。

退回php的根目录,运行

make

修改say_hello.php为

<?

       Say_hello(“yorgo”);

?>

保存退出后运行

./php ?q say_hello.php

得出结果

hello world, yorgo

表示我们这次的修改也成功了,可以改变say_hello中的参数,看看动态的效果。

这里主要解释上面修改的函数内容,由于say_hello函数需要有参数引入,所以在my_module.c中的say_hello函数主要在进行参数的处理,将php中引用say_hello时所填写的参数内容正确的传递到my_module.c中的say_hello处理函数中。为此,程序中添加了这么几行。

zval **yourname;

if (ZEND_NUM_ARGS() != 1
zend_get_parameters_ex(1, &yourname) == FAILURE)

{

WRONG_PARAM_COUNT;

}

zend_printf("hello world, %s\n", Z_STRVAL_PP(yourname));

  

代码解释如下:

zval **yourname;

初始化一个参数的指针

ZEND_NUM_ARGS()

得到传递过来得参数数量,并且判断如果不为1的时候表示有问题,报错。

zend_get_parameters_ex(1, &yourname)

将刚刚初始化的指针指向传递过来的参数,如果不成功则报错。

Z_STRVAL_PP(yourname)

处理指针指向的参数并获得实际存储的值。

(待续)

PHP 相关文章推荐
PHP 常见郁闷问题答解
Nov 25 PHP
发布一个迷你php+AJAX聊天程序[聊天室]提供下载
Jul 21 PHP
坏狼的PHP学习教程之第1天
Jun 15 PHP
php discuz 主题表和回帖表的设计
Mar 13 PHP
php 静态变量与自定义常量的使用方法
Jan 26 PHP
PHP中通过HTTP_USER_AGENT判断是否为手机移动终端的函数代码
Feb 14 PHP
PHP的魔术常量__METHOD__简介
Jul 08 PHP
PHP+Ajax检测用户名或邮件注册时是否已经存在实例教程
Aug 23 PHP
Windows下编译PHP5.4和xdebug全记录
Apr 03 PHP
php mysql_list_dbs()函数用法示例
Mar 29 PHP
php获取文章内容第一张图片的方法示例
Jul 03 PHP
laravel框架 api自定义全局异常处理方法
Oct 11 PHP
PHP输出控制功能在简繁体转换中的应用
Oct 09 #PHP
PHP 中执行系统外部命令
Oct 09 #PHP
PHP实现文件安全下载
Oct 09 #PHP
PHP - Html Transfer Code
Oct 09 #PHP
关于PHP中操作MySQL数据库的一些要注意的问题
Oct 09 #PHP
模拟xcopy的函数
Oct 09 #PHP
生成缩略图
Oct 09 #PHP
You might like
Win2000+Apache+MySql+PHP4+PERL安装使用小结
2006/10/09 PHP
在项目中寻找代码的坏命名
2012/07/14 PHP
PHP 文件系统详解
2012/09/13 PHP
php实现把url转换迅雷thunder资源下载地址的方法
2014/11/07 PHP
利用laravel搭建一个迷你博客实战教程
2017/08/13 PHP
微信公众平台开发教程⑤ 微信扫码支付模式介绍
2019/04/10 PHP
php中yii框架实例用法
2020/12/22 PHP
jquery操作checked属性以及disabled属性的多种方法
2014/06/20 Javascript
javascript中为某个元素指定事件的三种方式
2014/08/07 Javascript
jQuery实现的导航条切换可显示隐藏
2014/10/22 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
每天一篇javascript学习小结(Boolean对象)
2015/11/12 Javascript
jquery简单插件制作(fn.extend)完整实例
2016/05/24 Javascript
关于Sequelize连接查询时inlude中model和association的区别详解
2017/02/27 Javascript
如何选择jQuery版本 1.x? 2.x? 3.x?
2017/04/01 jQuery
详解RequireJS按需加载样式文件
2017/04/12 Javascript
javascript完美实现给定日期返回上月日期的方法
2017/06/15 Javascript
DVA框架统一处理所有页面的loading状态
2017/08/25 Javascript
详解create-react-app 自定义 eslint 配置
2018/06/07 Javascript
vue配置接口域名方法总结
2019/05/12 Javascript
JS实现点击下拉列表文本框中出现对应的网址,点击跳转按钮实现跳转
2019/11/25 Javascript
浅谈MySQL中的触发器
2015/05/05 Python
python获取指定目录下所有文件名列表的方法
2015/05/20 Python
python实现linux下抓包并存库功能
2018/07/18 Python
python列表推导和生成器表达式知识点总结
2020/01/10 Python
PyCharm设置Ipython交互环境和宏快捷键进行数据分析图文详解
2020/04/23 Python
让Django的BooleanField支持字符串形式的输入方式
2020/05/20 Python
SKECHERS斯凯奇中国官网:来自美国的运动休闲品牌
2018/11/14 全球购物
丝芙兰墨西哥官网:Sephora墨西哥
2020/05/30 全球购物
英语专业毕业生自我鉴定
2013/11/09 职场文书
基层干部十八大感言
2014/01/19 职场文书
党的群众路线教育实践活动学习笔记范文
2014/11/06 职场文书
幼儿园教师安全责任书
2015/05/08 职场文书
祝酒词范文
2015/08/12 职场文书
敬业奉献模范事迹材料(2016精选版)
2016/02/26 职场文书
教你怎么用python实现字符串转日期
2021/05/24 Python