当前位置:首页 > PHP教程 > PHP常见问题

一个非常完美的读写ini格式的PHP配置类分享

基本满足所有配置相关的需求。

/** * 解析.ini格式的配置文件为一个树形结构的对象 
 * 配置文件不同section通过冒号继承 
 * 默认根据hostname确定使用的section,如果不能确定就优先使用production 
 * 检测环境的时候总是优先检测production,其余section按定义顺序检测 
 * */ 
class config { 
 /** * 解析后的配置文件
 * * @var stdclass
 */ 
 private $config; 
 /** * 一个二维数组,键是配置文件的section 
 * 值是一个数组或回调函数 
 * 如果是数组则计算hostname是否在数组中决定是否使用该section 
 * 如果是回调函数通过返回值true或false来确定是否使用该section 
 * * @var array 
 */
 private $map = array (); 
 /** * section会被解析,:表示继承 * 配置项中的'.'用来区分层级关系 
 * section中的'.'不会被解析,配置中的数组不受影响。
 * * @param string $conf 
 * @throws errorexception 
 * @return stdclass

 */ 

 function __construct($conf, $map) { 

 $config = $this->parseini ( ( object ) parse_ini_string ( $conf, true ) );

 if (array_key_exists ( 'production', $map )) { 

 $production = $map ['production'];

 unset ( $map ['production'] ); 

 $map = array_merge ( array ( 'production' => $production ), $map );

 } else {

 throw new errorexception ( 'production section not found in config' ); 

 } 

 $section = 'production';

 $hostname = gethostname (); 

 foreach ( $map as $k => $v ) {

 if (is_array ( $v )) {

 foreach ( $v as $v1 ) {

 if ($v1 == $hostname) { $section = $k; break 2; 

 } 

 } 

 } elseif (is_callable ( $v )) { 

 if (true == call_user_func ( $v )) {

 $section = $k; break; 

 } 

 } else { 

 throw new errorexception ( 'wrong map value in ' . __class__ );

 } 

 } 

 $this->config = $config->$section; 

 } 

 /** * 总是返回配置对象 

 * * @return mixed 

 */ 

 function __get($key) {

 if (isset ( $this->config->$key )) { 

 return $this->config->$key; 

 } 

 } 

 /** * 切分 

 * * @param stdclass $v

 * @param string $k1

 * @param mixed $v1 

 */

 private function split($v, $k1, $v1) { 

 $keys = explode ( '.', $k1 ); 

 $last = array_pop ( $keys );

 $node = $v;

 foreach ( $keys as $v2 ) { 

 if (! isset ( $node->$v2 )) { 

 $node->$v2 = new stdclass ();

 } 

 $node = $node->$v2;

 } 

 $node->$last = $v1;

 if (count ( $keys ) > 0) { 

 unset ( $v->$k1 );

 }

}

 /** * parseini 

 * * @param object $conf 

 * @return stdclass 

 */

 private function parseini($conf) { 

 $confobj = new stdclass ();

 foreach ( $conf as $k => $v ) { // 是section

 if (is_array ( $v )) {

 $confobj->$k = ( object ) $v; 

 foreach ( $v as $k1 => $v1 ) { 

 call_user_func ( array ( $this, 'split' ), $confobj->$k, $k1, $v1 );

 }

 } else { 

 call_user_func ( array ( $this, 'split' ), $confobj, $k, $v ); 

 } 

 }

 unset ( $conf ); // 处理继承 

 foreach ( $confobj as $k => $v ) {

 if (false !== strpos ( $k, ':' )) {

 if (0 === strpos ( $k, ':' )) { 

 throw new errorexception ( 'config ' . $k . ' is invalid, ':' can't be the first char' );

 } elseif (1 < substr_count ( $k, ':' )) {

 throw new errorexception ( 'config ' . $k . ' is invalid, ':' can appear only once' );

 } else { $keys = explode ( ':', $k );

 if (! isset ( $confobj->$keys [1] )) { 

 throw new errorexception ( 'parent section ' . $keys [1] . ' doesn't exist in config file' ); 

 } else { if (isset ( $confobj->$keys [0] )) { 

 throw new errorexception ( 'config is invalid, ' . $keys [0] . ' and ' . $k . ' conflicts' );

 } else { 

 $confobj->$keys [0] = $this->deepcloner ( $confobj->$keys [1] );

 $this->objectmerger ( $confobj->$keys [0], $v );

 unset ( $confobj->$k ); 

 }

 } 

 } 

 }

 } 

 return $confobj; } 

 /** * php默认是浅克隆,函数实现深克隆

 * * @param object $obj 

 * @return object $obj 

 */ 

 private function deepcloner($obj) { 

 $objclone = clone $obj; foreach ( $objclone as $k => $v ) {

 if (is_object ( $v )) {

 $objclone->$k = $this->deepcloner ( $v );

 } } 

 return $objclone;

 /** * 递归的合并两个对象 

 * * @param unknown $obj1 

 * @param unknown $obj2 

 */ 

 private function objectmerger($obj1, $obj2) {

 foreach ( $obj2 as $k => $v ) {

 if (is_object ( $v ) && isset ( $obj1->$k ) && is_object ( $obj1->$k )) {

 $this->objectmerger ( $obj1->$k, $v ); } else {

 $obj1->$k = $v;

 }

 } 

 } 

}

简单使用:

$_env ['config'] = new config ( file_get_contents ( __dir__ . '/config.ini' ), array ( 'development' => array ( 'localhost.localdomain', 'localhost' ), 'production' => array () ) );

配置文件示例:

[product] db.default.dsn="mysql:host=127.0.0.1;dbname=default" db.default.username=root db.default.password=123456 admin.username=admin admin.password=123456
 php.error_reporting=e_all
php.display_errors=no 
php.log_errors=yes 
php.error_log=app_path
'/resource/log/phperror.log'
 php.session.save_path=app_path
'/resource/data/session' 
 [development:product] 
db.test1.dsn="mysql:host=127.0.0.1;dbname=test1" db.test1.username=root db.test1.password=123456 php.display_errors=yes



【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!