注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

又一个部落格

换过很多备忘录,不知道这本怎么样!

 
 
 

日志

 
 

ubuntu php c 扩展  

2010-03-17 17:00:22|  分类: c |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |


php使用 dl()函数动态的加载 外部模块. 当脚本执行完毕后,外部模块将被丢弃.
这样的方式既有优点也有缺点
优点: 不需要重新编译php
通过这种方式,php核心功能始终很小巧.不会变的很庞大.
缺点: 当用户每次点击时,都需要重新的进行加载,这样速度上会比较慢
    外部文件杂乱,不容易管理
    当要使用时,都需要调用 dl()函数


php源代码结构
php4 主要PHP源文件和主要的头文件,在这里你会发现PHP的API的定义,宏等(重要的)。
php4/ext 动态的和内置的模块库.默认情况下,这些都是zend官方的集成模块.
php4/main 此目录包含PHP主宏和预编译。 (重要的)
php4/pear 包含了php的扩展和应用库。此目录包含核心PEAR的文件。
php4/sapi 包含不同的服务器抽象层的代码。
php4/TSRM TSRM(Thread Safe Resource Manager).线程安全资源管理.
php4/Zend zend引擎文件.在这里可以找到所有的zend api的定义和宏.

几个重要需要了解的文件
php4/main/php.h 这里包含了大部分的php宏和php api 定义
php4/Zend/zend.h 这里包含大部分的 zend宏和预编译
php4/Zend/zend_API.h 包含了大部分的zend api定义

内存分配
有两种方式的内存分配
1.持久分配 请求完毕后不会释放内存
2.临时分配 当一个请求完毕后就释放内存

传统 非持久性 持久性
malloc(count) emalloc(count) pemalloc(count, 1)
calloc(count, num) ecalloc(count, num) pecalloc(count, num, 1)
strdup(str) estrdup(str) pestrdup(str, 1)
strndup(str, len) estrndup(str, len) pemalloc() & memcpy()
free(ptr) efree(ptr) pefree(ptr, 1)
realloc(ptr, newsize) erealloc(ptr, newsize) perealloc(ptr, newsize, 1)
malloc(count * num + extr) safe_emalloc(count, num, extr) safe_pemalloc(count, num, extr)


先下载php的源码包,解压,我这里下的是 php-5.2.6
自动创建 .m4等文件
/.../php-5.2.6-src/ext# ./ext_skel --extname=hello

修改.m4文件 删除下面三行前面的 dnl
dnl PHP_ARG_ENABLE(hello, whether to enable hello support,
dnl Make sure that the comment is aligned:
dnl [ --enable-hello Enable hello support])

修改 php_hello.h
#ifndef PHP_HELLO_H
#define PHP_HELLO_H 1

#define PHP_HELLO_WORLD_VERSION "1.0"
#define PHP_HELLO_WORLD_EXTNAME "hello"

PHP_FUNCTION(hello_world);

extern zend_module_entry hello_module_entry;
#define phpext_hello_ptr &hello_module_entry

#endif


修改 hello.c
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_hello.h"

static function_entry hello_functions[] = {
PHP_FE(hello_world, NULL)
{NULL, NULL, NULL}
};

zend_module_entry hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_HELLO_WORLD_EXTNAME,
hello_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_HELLO_WORLD_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_HELLO
ZEND_GET_MODULE(hello)
#endif

PHP_FUNCTION(hello_world)
{
RETURN_STRING("Hello World", 1);
}

上面的这种写法,虽然不会报错,其实存在问题,字符串 Hello World 被释放两次.
正确的写法应该是
PHP_FUNCTION(hello_world)
{
char *str;

str = estrdup("Hello World");
RETURN_STRING(str, 0);
}


编译步骤,如果没有安装phpize 那么先安装 apt-get install php5dev
phpize
./configure --enable-hello
make

编译完成后一般会在 modules 目录下面找到 hello.so 文件
拷贝到 ubuntu的php扩展目录
/usr/lib/php5/20060613+lfs

修改 php.ini文件 增加行
extsion=hello.so

重启apache
/etc/init.d/apache2 restart

写一测试程序
<?php
echo hello_world;

运行测试

我们再往里面添加一些返回其他类型的hello函数
修改 php_hello.h,添加下面函数原型
PHP_FUNCTION(hello_long);
PHP_FUNCTION(hello_double);
PHP_FUNCTION(hello_bool);
PHP_FUNCTION(hello_null);

修改 hello.c
static function_entry hello_functions[] = {
PHP_FE(hello_world, NULL)
PHP_FE(hello_long, NULL)
PHP_FE(hello_double, NULL)
PHP_FE(hello_bool, NULL)
PHP_FE(hello_null, NULL)
{NULL, NULL, NULL}
};

PHP_FUNCTION(hello_long)
{
RETURN_LONG(42);
}

PHP_FUNCTION(hello_double)
{
RETURN_DOUBLE(3.1415926535);
}

PHP_FUNCTION(hello_bool)
{
RETURN_BOOL(1);
}

PHP_FUNCTION(hello_null)
{
RETURN_NULL();
}

因为没有修改.m4文件.所以重新编译直接跳过 phpize和 ./configure
先运行 make clean 确保下次make完全重新编译
运行 make重新编译
拷贝覆盖到扩展目录
重启web服务器
测试
<?php
echo hello_world(), '<br/>';
echo hello_long(), '<br/>';
echo hello_double(), '<br/>';
echo hello_bool(), '<br/>';
echo hello_null(), '<br/>';


上面的
RETURN_BOOL(1); 可以使用 宏 RETURN_TRUE; 代替

下面是怎么简单的存取 php.ini 配置文件
修改php_hello.h文件 添加两函数原型
PHP_MINIT_FUNCTION(hello);
PHP_MSHUTDOWN_FUNCTION(hello);

修改 hello.c 文件
在头部加入 include

#include "php_ini.h"

修改hello_module_entry 到现在的版本

zend_module_entry hello_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
PHP_HELLO_WORLD_EXTNAME,
hello_functions,
PHP_MINIT(hello),
PHP_MSHUTDOWN(hello),
NULL,
NULL,
NULL,
#if ZEND_MODULE_API_NO >= 20010901
PHP_HELLO_WORLD_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
};

PHP_INI_BEGIN()
PHP_INI_ENTRY("hello.greeting", "Hello World!", PHP_INI_ALL, NULL)
PHP_INI_END()

PHP_MINIT_FUNCTION(hello)
{
REGISTER_INI_ENTRIES();

return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(hello)
{
UNREGISTER_INI_ENTRIES();

return SUCCESS;
}

修改函数 hello_world
PHP_FUNCTION(hello_world)
{
RETURN_STRING(INI_STR("hello.greeting"), 1);
}

这样就实现了 注册一个ini值 和取一个ini值.以及最后删除ini值
PHP_MINIT_FUNCTION PHP_MSHUTDOWN_FUNCTION 这两个函数只有在 比如 apache启动和关闭的时候才会执行

  评论这张
 
阅读(1163)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017