首页 > 开发 > PHP > 正文

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

2024-05-04 23:31:17
字体:
来源:转载
供稿:网友

这篇文章主要介绍了一个非常完美的读写ini格式的PHP配置类分享,本文给出类代码、使用例子和配置文件例子,需要的朋友可以参考下

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

 

 
  1. /** 
  2. * 解析.ini格式的配置文件为一个树形结构的对象 
  3. * 配置文件不同section通过冒号继承 
  4. * 默认根据hostname确定使用的section,如果不能确定就优先使用production 
  5. * 检测环境的时候总是优先检测production,其余section按定义顺序检测 
  6. * 
  7. * @author ares@phpdr.net 
  8.  
  9. */ 
  10. class Config { 
  11. /** 
  12. * 解析后的配置文件 
  13. * 
  14. * @var stdClass 
  15. */ 
  16. private $config
  17. /** 
  18. * 一个二维数组,键是配置文件的section 
  19. * 值是一个数组或回调函数 
  20. * 如果是数组则计算hostname是否在数组中决定是否使用该section 
  21. * 如果是回调函数通过返回值true或false来确定是否使用该section 
  22. * 
  23. * @var array 
  24. */ 
  25. private $map = array (); 
  26.  
  27. /** 
  28. * section会被解析,:表示继承 
  29. * 配置项中的'.'用来区分层级关系 
  30. * section中的'.'不会被解析,配置中的数组不受影响。 
  31. * 
  32. * @param string $conf  
  33. * @throws ErrorException 
  34. * @return stdClass 
  35. */ 
  36. function __construct($conf$map) { 
  37. $config = $this->parseIni ( ( object ) parse_ini_string ( $conf, true ) ); 
  38. if (array_key_exists ( 'production'$map )) { 
  39. $production = $map ['production']; 
  40. unset ( $map ['production'] ); 
  41. $map = array_merge ( array ( 
  42. 'production' => $production ), $map ); 
  43. else { 
  44. throw new ErrorException ( 'production section not found in config' ); 
  45. $section = 'production'
  46. $hostname = gethostname (); 
  47. foreach ( $map as $k => $v ) { 
  48. if (is_array ( $v )) { 
  49. foreach ( $v as $v1 ) { 
  50. if ($v1 == $hostname) { 
  51. $section = $k
  52. break 2; 
  53. elseif (is_callable ( $v )) { 
  54. if (true == call_user_func ( $v )) { 
  55. $section = $k
  56. break
  57. else { 
  58. throw new ErrorException ( 'Wrong map value in ' . __CLASS__ ); 
  59. $this->config = $config->$section
  60.  
  61. /** 
  62. * 总是返回配置对象 
  63. * 
  64. * @return mixed 
  65. */ 
  66. function __get($key) { 
  67. if (isset ( $this->config->$key )) { 
  68. return $this->config->$key
  69.  
  70. /** 
  71. * 切分 
  72. * 
  73. * @param stdClass $v  
  74. * @param string $k1  
  75. * @param mixed $v1  
  76. */ 
  77. private function split($v$k1$v1) { 
  78. $keys = explode ( '.'$k1 ); 
  79. $last = array_pop ( $keys ); 
  80. $node = $v
  81. foreach ( $keys as $v2 ) { 
  82. if (! isset ( $node->$v2 )) { 
  83. $node->$v2 = new stdClass (); 
  84. $node = $node->$v2
  85. $node->$last = $v1
  86. if (count ( $keys ) > 0) { 
  87. unset ( $v->$k1 ); 
  88.  
  89. /** 
  90. * parseIni 
  91. * 
  92. * @param object $conf  
  93. * @return stdClass 
  94. */ 
  95. private function parseIni($conf) { 
  96. $confObj = new stdClass (); 
  97. foreach ( $conf as $k => $v ) { 
  98. // 是section 
  99. if (is_array ( $v )) { 
  100. $confObj->$k = ( object ) $v
  101. foreach ( $v as $k1 => $v1 ) { 
  102. call_user_func ( array ( 
  103. $this
  104. 'split' ), $confObj->$k$k1$v1 ); 
  105. else { 
  106. call_user_func ( array ( 
  107. $this
  108. 'split' ), $confObj$k$v ); 
  109. unset ( $conf ); 
  110. // 处理继承 
  111. foreach ( $confObj as $k => $v ) { 
  112. if (false !== strpos ( $k':' )) { 
  113. if (0 === strpos ( $k':' )) { 
  114. throw new ErrorException ( 'config ' . $k . ' is invalid, ':' can't be the first char' ); 
  115. elseif (1 < substr_count ( $k':' )) { 
  116. throw new ErrorException ( 'config ' . $k . ' is invalid, ':' can appear only once' ); 
  117. else { 
  118. $keys = explode ( ':'$k ); 
  119. if (! isset ( $confObj->$keys [1] )) { 
  120. throw new ErrorException ( 'parent section ' . $keys [1] . ' doesn't exist in config file' ); 
  121. else { 
  122. if (isset ( $confObj->$keys [0] )) { 
  123. throw new ErrorException ( 'config is invalid, ' . $keys [0] . ' and ' . $k . ' conflicts' ); 
  124. else { 
  125. $confObj->$keys [0] = $this->deepCloneR ( $confObj->$keys [1] ); 
  126. $this->objectMergeR ( $confObj->$keys [0], $v ); 
  127. unset ( $confObj->$k ); 
  128. return $confObj
  129.  
  130. /** 
  131. * php默认是浅克隆,函数实现深克隆 
  132. * 
  133. * @param object $obj  
  134. * @return object $obj 
  135. */ 
  136. private function deepCloneR($obj) { 
  137. $objClone = clone $obj
  138. foreach ( $objClone as $k => $v ) { 
  139. if (is_object ( $v )) { 
  140. $objClone->$k = $this->deepCloneR ( $v ); 
  141. return $objClone
  142.  
  143. /** 
  144. * 递归的合并两个对象 
  145. * 
  146. * @param unknown $obj1  
  147. * @param unknown $obj2  
  148. */ 
  149. private function objectMergeR($obj1$obj2) { 
  150. foreach ( $obj2 as $k => $v ) { 
  151. if (is_object ( $v ) && isset ( $obj1->$k ) && is_object ( $obj1->$k )) { 
  152. $this->objectMergeR ( $obj1->$k$v ); 
  153. else { 
  154. $obj1->$k = $v

简单使用:

 

 
  1. $_ENV ['config'] = new Config ( file_get_contents ( __DIR__ . '/config.ini' ), array ( 
  2. 'development' => array ( 
  3. 'localhost.localdomain'
  4. 'localhost' 
  5. ), 
  6. 'production' => array () 
  7. ) ); 

配置文件示例:

 

 
  1. [product] 
  2. db.default.dsn="mysql:host=127.0.0.1;dbname=default" 
  3. db.default.username=root 
  4. db.default.password=123456 
  5.  
  6. admin.username=admin 
  7. admin.password=123456 
  8.  
  9. php.error_reporting=E_ALL 
  10. php.display_errors=no 
  11. php.log_errors=yes 
  12. php.error_log=APP_PATH'/resource/log/phpError.log' 
  13. php.session.save_path=APP_PATH'/resource/data/session' 
  14.  
  15. [development:product] 
  16. db.test1.dsn="mysql:host=127.0.0.1;dbname=test1" 
  17. db.test1.username=root 
  18. db.test1.password=123456 
  19. php.display_errors=yes 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表