描述了say_hello函数的具体内容,调用zend_printf系统函数在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 2881064151|| 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)
处理指针指向的参数并获得实际存储的值。
描述了say_hello函数的具体内容,调用zend_printf系统函数在php中打印字符串的更多相关文章
- C#-等待异步函数执行结果-将调用异步方法的函数变成非异步执行
先来简单了解一下async.await 使用async await 的前提条件:需要C# 5.0以上版本 .NET Framework 4.5以上 Visual Studio 2012以上. asyn ...
- sql server 函数详解(5)系统函数
返回表中指定字段的长度 返回表中指定字段的名称 返回数据表达式的数据的实际长度函数 返回数据库的编号 返回数据库的名称 返回数据库当前默认的null值 返回服务器端计算机的标识号 返回服务 ...
- 用servlet在网页中打印字符串(初接触)、servlet调用过程
一.servlet是什么: 二.在官方文档中点servlet 这就是servlet的方法,这里说一下什么叫生命周期的方法(life-cycle methods):就是这个对象一旦创生之后一定会执行的方 ...
- 介绍了如何取成员函数的地址以及调用该地址:C++
摘要:介绍了如何取成员函数的地址以及调用该地址. 关键字:C++成员函数 this指针 调用约定 一.成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西.对普通的函数指针来说,可以视为一 ...
- C#调用Windows API函数截图
界面如下: 下面放了一个PictureBox 首先是声明函数: //这里是调用 Windows API函数来进行截图 //首先导入库文件 [System.Runtime.InteropServices ...
- C#基础知识-函数的定义和调用(五)
函数也可以称为方法,可以很方便的把一些行为封装到函数里面,当调用这一函数时会把函数块里面的代码按照顺序执行,方法可以有多种形式,有无参数,有无返回值等. 1. 函数的定义 函数定义的基本格式: s ...
- Linux网络编程2——系统函数
socket信息数据结构 #include <netinet/in.h> struct sockaddr { unsigned short sa_family; /*地址族*/ ]; /* ...
- 内联函数背景、例子、与普通函数的区别及要注意的地方 ------新标准c++程序设计
背景: 使用函数能够避免将相同代码重些多次的烦恼,还能减少可执行程序的体积,但也会带来程序运行时间上的开销.函数调用在执行时,首先在栈中为形参和局部变量分配存储空间,然后还要将实参的值复制给形参,接下 ...
- MSSQL sqlserver系统函数教程分享
摘要: 下文收集了sqlserver函数教程,为每一个函数都进行了相关举例说明, 如下所示: sqlserver聚合函数教程: mssql sqlserver avg聚合函数使用简介 mssql sq ...
随机推荐
- Cocos2d-x 学习资料推荐
最近在看Cocos2d-x ,官网的资料太少了,下面推荐一些比较好的教程,不断更新中. 1. cocos2d-x高级开发教程 如果你懂得objective-c 那么一定要看看这本书,这里面有许多C++ ...
- Linux系统排查3——I/O篇
当磁盘无法写入的时候,一般有以下可能: 文件系统只读 磁盘已满 I节点使用完 一. 遇到只读的文件系统 文件系统自动设置成只读可能是系统自我保护的一种机制,因此需要实现弄清究竟是什么原因造成了文件系统 ...
- 【pymongo】连接认证 auth failed解决方法
故事背景: 我在虚拟机(ip:192.168.xx.xx)上建立了一个mongo的数据库,里面已经存好了内容.里面的一个database叫做 "adb", 里面有个collecti ...
- plsql查询数据显示为乱码解决方法
使用plsql查询数据显示为乱码: 查看数据库编码: 通过网上搜索,发现需要设置环境变量,添加以下环境变量: LANG=zh_CN.GBK NLS_LANG="SIMPLIFIED CHIN ...
- MFC 线程
//新开一个线程去处理新的工作,可以传一个参数 class MyClass//自定义一个类 { void fun(){} ... } MyClass* myObject=new MyClass;Afx ...
- July 20th, Week 30th Wednesday, 2016
Learn from yesterday, live for today, and hope for tomorrow. 借鉴昨天,活着当下,憧憬未来. Yesterday is the past, ...
- javascript类的类比详解-大白话版
转载请注明出处:水车 如果有误,还望指出,谢谢 -----------------正文分割线---------------------- 类:类太抽象,要想弄明白就该用现实的东西来类比 在我看来类就是 ...
- 正则和xml解析
一般来说是xml解析的开销比正则大些.使用正则搜索,只需搜索<second>就能定位到你要的内容,而xml解析要把节点树在内存中建立起来,所以消耗内存会多些,速度可能会受到一些影响.但对于 ...
- 大神的游戏(codevs 1353)
题目描述 Description 在那遥远的机房,有一片神奇的格子.为了方便起见,我们编号为1~n.传说只要放入一些卡片,就能实现愿望.卡片一共有m种颜色,但是相邻的格子间不能放入相同颜色的卡片.只要 ...
- hdu 4006 优先队列 2011大连赛区网络赛F **
签到题都要想一会 #include<cstdio> #include<iostream> #include<algorithm> #include<cstri ...