首页 > 后端开发 > php教程 > 一个非常完美的读写ini格式的PHP配置类分享_PHP

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

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
发布: 2016-05-31 13:17:04
原创
1000 人浏览过

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

/**

 * 解析.ini格式的配置文件为一个树形结构的对象

 * 配置文件不同section通过冒号继承

 * 默认根据hostname确定使用的section,如果不能确定就优先使用production

 * 检测环境的时候总是优先检测production,其余section按定义顺序检测

 *

 * @author ares@phpdr.net

 *   

 */

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;

  }

 }

 }

}

登录后复制

简单使用:

1

2

3

4

5

6

7

$_ENV ['config'] = new Config ( file_get_contents ( __DIR__ . '/config.ini' ), array (

 'development' => array (

  'localhost.localdomain',

  'localhost'

 ),

 'production' => array ()

) );

登录后复制

配置文件示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[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

登录后复制

相关标签:
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
读写分离
来自于 1970-01-01 08:00:00
0
0
0
java - 读写锁中 写锁的降级问题
来自于 1970-01-01 08:00:00
0
0
0
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板