深入理解php中的ini配置(1) - 商讯 - 长春市隆兴伟业物流有限公司
现在的位置: 主页 > 商讯 > 文章正文
深入理解php中的ini配置(1)
作者:长春市隆兴伟业物流有限公司 来源:www.lxwywl.com 发布时间:2017-09-03 12:16:34
深入理解php中的ini配置(1) 这篇文章不会详细叙述某个ini配置项的用途,这些在手册上已经讲解的面面俱到。我只是想从某个特定的角度去挖掘php的实现机制,会涉及到一些php内核方面的知识:-)

使用php的同学都知道php.ini配置的生效会贯穿整个SAPI的生命周期。在一段php脚本的执行过程中,如果手动修改ini配置,是不会启作用的。此时如果无法重启apache或者nginx等,那么就只能显式的在php代码中调用ini_set接口。ini_set是php向我们提供的一个动态修改配置的函数,需要注意的是,利用ini_set所设置的配置与ini文件中设置的配置,其生效的时间范围并不相同。在php脚本执行结束之后,ini_set的设置便会随即失效。

因此本文打算分两篇,第一篇阐述php.ini配置原理,第二篇讲动态修改php配置。

php.ini的配置大致会涉及到三块数据,configuration_hash,EG(ini_directives)以及PG、BG、PCRE_G、JSON_G、XXX_G等。如果不清楚这三种数据的含义也没有关系,下文会详细解释。

1,解析INI配置文件

由于php.ini需要在SAPI过程中一直生效,那么解析ini文件并据此来构建php配置的工作,必定是发生SAPI的一开始。换句话说,也就是必定发生在php的启动过程中。php需要任意一个实际的请求到达之前,其内部已经生成好这些配置。

反映到php的内核,即为php_module_startup函数。

php_module_startup主要负责对php进行启动,通常它会在SAPI开始的时候被调用。btw,还有一个常见的函数是php_request_startup,它负责将在每个请求到来的时刻进行初始化,php_module_startup与php_request_startup是两个标识性的动作,不过对他们进行分析并不在本文的探讨范围内。

举个例子,当php挂接在apache下面做一个module,那么apache启动的时候,便会激活所有这些module,其中包括php module。在激活php module时,便会调用到php_module_startup。php_module_startup函数完成了茫茫多的工作,一旦php_module_startup调用结束就意味着,OK,php已经启动,现在可以接受请求并作出响应了。

在php_module_startup函数中,与解析ini文件相关的实现是:

/* this will read in php.ini, set up the configuration parameters,

load zend extensions and register php function extensions

to be loaded later */

if (php_init_config(TSRMLS_C) == FAILURE) {

return FAILURE;

}

可以看到,其实就是调用了php_init_config函数,去完成对ini文件的parse。parse工作主要进行lex&grammar分析,并将ini文件中的key、value键值对提取出来并保存。php.ini的格式很简单,等号左侧为key,右侧为value。每当一对kv被提取出来之后,php将它们存储到哪儿呢?答案就是之前提到的configuration_hash。

static HashTable configuration_hash;

configuration_hash声明在php_ini.c中,它是一个HashTable类型的数据结构。顾名思义,其实就是张hash表。题外话,在php5.3之前的版本是没法获取configuration_hash的,因为它是php_ini.c文件的一个static的变量。后来php5.3添加了php_ini_get_configuration_hash接口,该接口直接返回&configuration_hash,使 得php各个扩展可以方便的一窥configuration_hash全貌...真是普大喜奔...

注意四点:

第一,php_init_config不会做除了词法语法以外的任何校验。也就是说,假如我们在ini文件中添加一行 hello=world,只要这是一个格式正确的配置项,那么最终configuration_hash中就会包含一个键为hello、值为world的元素,configuration_hash最大限度的反映出ini文件。

第二,ini文件允许我们以数组的形式进行配置。例如ini文件中写入以下三行:

drift.arr[]=1

drift.arr[]=2

drift.arr[]=3

那么最终生成的configuration_hash表中,就会存在一个key为drift.arr的元素,其value为一个包含的1,2,3三个数字的数组。这是一种极为罕见的配置方法。

第三,php还允许我们除了默认的php.ini文件(准确说是php-%s.ini)之外,另外构建一些ini文件。这些ini文件会被放入一个额外的目录。该目录由环境变量PHP_INI_SCAN_DIR来指定,当php_init_config解析完了php.ini之后,会再次扫描此目录,然后找出目录中所有.ini文件来分析。这些额外的ini文件中产生的kv键值对,也会被加入到configuration_hash中去。

这是一个偶尔有用的特性,假设我们自己开发php的扩展,却又不想将配置混入php.ini,便可以另外写一份ini,并通过PHP_INI_SCAN_DIR告诉php该去哪儿找到它。当然,其缺点也显而易见,其需要设置额外的环境变量来支持。更好的解决办法是,开发者在扩展中自己调用php_parse_user_ini_file或zend_parse_ini_file去解析对应的ini文件。

第四,在configuration_hash中,key是字符串,那么值的类型是什么?答案也是字符串(除了上述很特殊的数组)。具体来说,比如下面的配置:

display_errors = On

log_errors = Off

log_errors_max_len = 1024

那么最后configuration_hash中实际存放的键值对为:

key: "display_errors"

val : "1"

key: "log_errors"

val : ""

key: "log_errors_max_len"

val : "1024"

注意log_errors,其存放的值连"0"都不是,就是一个实实在在地空字符串。另外,站群,log_errors_max_len也并非数字,而是字符串1024。

分析至此,基本上解析ini文件相关的内容都说清楚了。简单总结一下:

1,解析ini发生在php_module_startup阶段

2,解析结果存放在configuration_hash里。

2,配置作用到模块

php的大致结构可以看成是最下层有一个zend引擎,它负责与OS进行交互、编译php代码、提供内存托管等等,在zend引擎的上层,排列着很多很多的模块。其中最核心的就一个Core模块,其他还有比如Standard,PCRE,Date,Session等等...这些模块还有另一个名字叫php扩展。我们可以简单理解为,每个模块都会提供一组功能接口给开发者来调用,举例来说,常用的诸如explode,trim,array等内置函数,便是由Standard模块提供的。

为什么需要谈到这些,是因为在php.ini里除了针对php自身,也就是针对Core模块的一些配置(例如safe_mode,display_errors,max_execution_time等),还有相当多的配置是针对其他不同模块的。

例如,date模块,它提供了常见的date, time,strtotime等函数。在php.ini中,它的相关配置形如:

[Date]

;date.timezone = 'Asia/Shanghai'

;date.default_latitude = 31.7667

;date.default_longitude = 35.2333

;date.sunrise_zenith = 90.583333

;date.sunset_zenith = 90.583333

除了这些模块拥有独立的配置,zend引擎也是可配的,只不过zend引擎的可配项非常少,只有error_reporting,zend.enable_gc和detect_unicode三项。

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:武汉网页设计 http://www.feimao666.com


  • 上一篇:Python序列——Unicode
  • 下一篇:最后一页
  • 
    COPYRIGHT © 2015 长春市隆兴伟业物流有限公司 ALL RIGHTS RESERVED.
    本站所有原创信息,未经许可请勿任意转载或复制使用 网站地图 技术支持:肥猫科技
    精彩专题:网站建设
    购买本站友情链接、项目合作请联系客服QQ:2500-38-100