php.ini文件是用来保存各项扩展配置的文件,每个扩展都或多或少需要有一个定制化的配置,ini文件是一个很好的保存配置的方式,我们来看下怎么在自己的扩展里,使用到ini的配置功能

//创建ini的配置项
#include "php_ini.h"

//ini配置的创建和全局变量的类似,通过宏定义创建一个结构体,来保存INI的配置项
//参数说明:
//1,配置名称
//2,配置值
//3,作用域
//4,修改时的回调函数,可以为NULL
PHP_INI_BEGIN()
PHP_INI_ENTRY("myext.ini_string","我是ini的字符串",PHP_INI_ALL,myext_example_ini_callback)
PHP_INI_ENTRY("myext.ini_long","",PHP_INI_ALL,NULL)
PHP_INI_END()

//在入口增加PHP_MSHUTDOWN(myext)函数
zend_module_entry myext_module_entry = {
#if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER,
#endif
"myext",//扩展名称
myext_functions,//zend_function_entry myext_functions 定义好的函数扩展变量
PHP_MINIT(myext),//MINIT_FUNCTION
PHP_MSHUTDOWN(myext),//PHP_MSHUTDOWN(myext),//MSHUTDOWN_FUNCTION
PHP_RINIT(myext),//RINIT_FUNCTION
PHP_RSHUTDOWN(myext),//RSHUTDOWN_FUNCTION
PHP_MINFO(myext),//MINFO_FUNCTION
#if ZEND_MODULE_API_NO >= 20010901
PHP_MYEXT_VERSION,
#endif
STANDARD_MODULE_PROPERTIES
}; PHP_MINIT_FUNCTION(myext)
{
//注册INI配置
REGISTER_INI_ENTRIES();
return SUCCESS;
} PHP_MSHUTDOWN_FUNCTION(myext)
{
//销毁INI配置
UNREGISTER_INI_ENTRIES();
return SUCCESS;
} //PHP_INI_ENTRY中的回调函数

ZEND_INI_MH(myext_example_ini_callback){
if(new_value_length == 0 || strcmp(new_value,"no_allow_string") == 0){
return FAILURE;
}
return SUCCESS;
}

/*

var_dump(ini_get('myext.ini_string'));
ini_set('myext.ini_string','我是新的INI字符串');
var_dump(ini_get('myext.ini_string'));
var_dump(ini_get('myext.ini_long'));
ini_set('myext.ini_long','101');
var_dump(ini_get('myext.ini_long'));

string(21) "我是ini的字符串"
string(24) "我是新的INI字符串"
string(3) "100"
string(3) "101"

*/

我们来看一下刚才PHP_INI_ENTRY函数中第三个参数作用域的问题

参数       描述
PHP_INI_PERDIR 指令可以在php.ini、httpd.conf或.htaccess文件中修改
PHP_INI_SYSTEM 指令可以在php.ini 和 httpd.conf 文件中修改
PHP_INI_USER 指令可以在用户脚本中修改
PHP_INI_ALL 指令可以在任何地方修改

怎么能在扩展中访问ini的配置项呢

PHP_FUNCTION(myext_example_ini);//php_myext.c

PHP_FE(myext_example_ini, NULL)//每个函数一行,第一个参数与PHP_FUNCTION(name)的name一样

PHP_FUNCTION(myext_example_ini){
const char * ini_string = INI_STR("myext.ini_string");//获取当前值
long ini_long = INI_INT("myext.ini_long");
php_printf("ini_string => %s\n",ini_string);
php_printf("ini_long => %ld\n",ini_long);
const char * orig_ini_string = INI_ORIG_STR("myext.ini_string");//获取默认值
long orig_ini_long = INI_ORIG_INT("myext.ini_long");
php_printf("orig_ini_string => %s\n",orig_ini_string);
php_printf("orig_ini_long => %ld\n",orig_ini_long);
} /*

myext_example_ini();
ini_set('myext.ini_string','我是新的INI字符串');
ini_set('myext.ini_long','101');
myext_example_ini();

 

ini_string => 我是ini的字符串
ini_long => 100
orig_ini_string => 我是ini的字符串
orig_ini_long => 100

//上面是修改前,下面是修改后

ini_string => 我是新的INI字符串
ini_long => 101
orig_ini_string => 我是ini的字符串
orig_ini_long => 100

*/

INI的配置项一共有四种类型,所有INI_STR和INI_ORIG_STR分别有四种不同类型的组合

#define INI_INT(name) zend_ini_long((name), sizeof(name), 0)
#define INI_FLT(name) zend_ini_double((name), sizeof(name), 0)
#define INI_STR(name) zend_ini_string_ex((name), sizeof(name), 0, NULL)
#define INI_BOOL(name) ((zend_bool) INI_INT(name)) #define INI_ORIG_INT(name) zend_ini_long((name), sizeof(name), 1)
#define INI_ORIG_FLT(name) zend_ini_double((name), sizeof(name), 1)
#define INI_ORIG_STR(name) zend_ini_string((name), sizeof(name), 1)
#define INI_ORIG_BOOL(name) ((zend_bool) INI_ORIG_INT(name))

在PHP_INI_ENTRY函数中第四个参数是一个回调函数,在ini配置项被修改的时候,这个函数会被调用,这个的作用在于,你可以对设置的值进行过滤,不符合要求的可以返回FAILER让本次修改不生效。

ZEND_INI_MH(myext_example_ini_callback){//这个函数需要用ZEND_INI_MH来定义,跟ZEND_FUNCTION不一样
if(new_value_length ==  || strcmp(new_value,"no_allow_string") == )//如果字符串为空或字符串=no_allow_string就不允许设置
{
return FAILURE; //本次修改不会生效
}
return SUCCESS;
} #define ZEND_INI_MH(name) int name(zend_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3, int stage TSRMLS_DC)
//宏展开以后这里有很多参数,这里面我们会用到的是修改值的new_value(字符串内容)和new_value_length(字符串长度),其余参数,内核会帮助我们自己补充,可以不需要关心

我们经常需要通过phpinfo或php -i来查询当前有效的ini配置项目,所以当我们开发扩展的时候,最好也把当前配置的信息写到PHP_MINFO_FUNCTION的函数中,结合前面说的MINFO部分的知识,以及刚才说到读取INI配置项的知识,我们可以自己实现这个功能,幸运的是,Zend的内核以及帮我们考虑到了,所有我们只要用以下代码就可以做到了。

PHP_MINFO_FUNCTION(myext){
php_info_print_table_start();
php_info_print_table_row(, "version", PHP_MYEXT_VERSION);
php_info_print_table_row(, "writer", "zhangxiaomin");
php_info_print_table_end(); DISPLAY_INI_ENTRIES();//只要增加这一行就可以了/
} /*
php5.6 -i //命令行

myext

version => 1.0
writer => zhangxiaomin

Directive => Local Value => Master Value
myext.ini_long => 100 => 100
myext.ini_string => 我是ini的字符串 => 我是ini的字符串

*/

到目前为止,我们已经能够在扩展中使用ini的配置了,但是实现起来不太理想,内核是用一个哈希表来保存配置项的数据的,每一次都需要一直zend_hash_find,然后保存的值都是字符串类型,查找到之后需要做类型转换,我们有什么方法来优化吗?如果你能想起全局变量,那就说明你慢慢对扩展有点感觉了。

ZEND_BEGIN_MODULE_GLOBALS(myext)
unsigned long counter;
char * global_ini_string;
char * global_ini_long;
ZEND_END_MODULE_GLOBALS(myext) PHP_INI_BEGIN()
PHP_INI_ENTRY("myext.ini_string","我是ini的字符串",PHP_INI_ALL,myext_example_ini_callback)
PHP_INI_ENTRY("myext.ini_long","",PHP_INI_ALL,NULL) STD_PHP_INI_ENTRY("myext.global_ini_string","i am global_ini_string",PHP_INI_ALL,OnUpdateString, global_ini_string, zend_myext_globals, myext_globals)
STD_PHP_INI_ENTRY("myext.global_ini_long","",PHP_INI_ALL,OnUpdateLong, global_ini_long, zend_myext_globals, myext_globals)
PHP_INI_END() PHP_FUNCTION(myext_example_ini){
const char * ini_string = INI_STR("myext.ini_string");
long ini_long = INI_INT("myext.ini_long");
php_printf("ini_string => %s\n",ini_string);
php_printf("ini_long => %ld\n",ini_long);
const char * orig_ini_string = INI_ORIG_STR("myext.ini_string");
long orig_ini_long = INI_ORIG_INT("myext.ini_long");
php_printf("orig_ini_string => %s\n",orig_ini_string);
php_printf("orig_ini_long => %ld\n",orig_ini_long); php_printf("global_ini_string => %s\n",MYEXT_G(global_ini_string));
php_printf("global_ini_long => %ld\n",MYEXT_G(global_ini_long));
} /*
这个地方有点问题,会导致php段错误,回头再查一下
*/

php扩展开发-INI配置的更多相关文章

  1. 基于Spring的可扩展Schema进行开发自定义配置标签支持

    一.背景 最近和朋友一起想开发一个类似alibaba dubbo的功能的工具,其中就用到了基于Spring的可扩展Schema进行开发自定义配置标签支持,通过上网查资料自己写了一个demo.今天在这里 ...

  2. 关于PHP扩展开发(收藏)

    一.Linux shell命令: ls –lh    查看文件大小 du –a    查看文件及文件夹大小 -------------------------- nginx ------------- ...

  3. mac+apache+php+phpmyadmin集成php开发环境配置

    刚开始才接触php才发现macos还是比较强大了,macbook不仅是时尚达品还很实用哦. --------------他山之石-------------------------- http://da ...

  4. 深入理解php中的ini配置(1)

    这篇文章不会详细叙述某个ini配置项的用途,这些在手册上已经讲解的面面俱到.我只是想从某个特定的角度去挖掘php的实现机制,会涉及到一些php内核方面的知识:-) 使用php的同学都知道php.ini ...

  5. PHP扩展开发相关总结

    1.线程安全宏定义 在TSRM/TSRM.h文件中有如下定义 #define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, ...

  6. php.ini配置中文详解

    ;;;;;;;;;;; ; 警告 ; ;;;;;;;;;;; ; 此配置文件是对于新安装的PHP的默认设置. ; 默认情况下,PHP使用此配置文件安装 ; 此配置针对开发目的,并且*不是*针对生产环境 ...

  7. PHP扩展开发(1):入门

    有关PHP扩展开发的文章.博客已经很多了,比较经典的有: TIPI项目(http://www.php-internals.com/,强烈推荐) <Extending and Embedding ...

  8. PHP扩展开发01:第一个扩展【转】

    我们先假设业务场景,是需要有这么一个扩展,提供一个叫ccvita_string的函数,他的主要作用是返回一段字符.(这个业务场景实在太假,大家就这么看看吧)对应的PHP代码可能是这样: functio ...

  9. Windows10系统PHP开发环境配置

    Windows下搭建(Apache+PHP+MySQL)=>WAMP Linux下搭建(Apache+PHP+MySQL) =>LAMP PHP开发环境配置一般有套件安装和自定义安装两种方 ...

随机推荐

  1. ACM-树重心的性质及动态维护

    本文转自http://fanhq666.blog.163.com/blog/static/81943426201172472943638/ 求树重心的方法:(NlogN) http://www.cnb ...

  2. Android Studio使用OpenCV的配置方法

    1.下载 进入官网(http://opencv.org/)下载OpenCV4Android并解压.目录结构如下图所示. 其中,sdk目录即是我们开发opencv所需要的类库:samples目录中存放着 ...

  3. Struts2 简介及学习方法介绍

    Struts2 =  webwork + struts1.x 尊重学习规律的操作 学习上痛苦的根源之一是只能走的时候逼我来跑 不是说深入的内容就不讲了,而是放到合适的时候讲 一段时间可以,长了集中不了 ...

  4. 笨办法学Python(七)

    习题 7: 更多打印 现在我们将做一批练习,在练习的过程中你需要键入代码,并且让它们运行起来.我不会解释太多,因为这节的内容都是以前熟悉过的.这节练习的目的是巩固你学到的东西.我们几个练习后再见.不要 ...

  5. Altium_Designer-各种布线总结

    1.常规布线:不详细说了,是个人就知道怎么弄.需要说明的是在布线过程中,可按小键盘的*键或大键盘的数字2键添加一个过孔:按L键可以切换布线层:按数字3可设定最小线宽.典型线宽.最大线宽的值进行切换. ...

  6. SAP CRM和C4C数据同步的两种方式概述:SAP PI和HCI

    SAP Cloud for Customer(C4C)和SAP其他传统产品进行数据同步的方式,如下图所示,可以使用SAP Netweaver Process Integration或者SAP HANA ...

  7. python里json的排序

    写一下json排序的问题: 将得到的数据转换成json格式传给ajax,会发现前台得到的数据很有可能和我们在后台的内容’不太一样‘,如果不出意外,json进行了自排序处理,至于按什么格式排的我还没研究 ...

  8. Android(java)学习笔记73:Intent启动Activity

    1. Intent启动Activity案例 (1)首先是main.xml和other.xml文件如下: main.xml文件: <?xml version="1.0" enc ...

  9. LA 3708 墓地雕塑

    题目链接:https://vjudge.net/contest/132704#problem/D 题意:一个长度为10000的园上,均匀分布n个雕塑,现在要加入m个雕塑,这样原先的就可能会移动,求移动 ...

  10. 字符串处理,Poj(2121)

    题目链接:http://poj.org/problem?id=2121 差一点就WA哭了,主要是自己傻逼了. 思路: 遇到hundred,sum*100; 但是遇到thouthend,million, ...