-
Notifications
You must be signed in to change notification settings - Fork 58
Expand file tree
/
Copy pathWindIniParser.php
More file actions
167 lines (159 loc) · 4.35 KB
/
WindIniParser.php
File metadata and controls
167 lines (159 loc) · 4.35 KB
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
<?php
/**
* ini 格式文件解析
*
* <note><b>注意:</b>有些保留字不能作为 ini 文件中的键名,<br/>
* 包括:null,yes,no,true 和 false。值为 null,no 和 false 等效于 "",<br/>
* 值为 yes 和 true 等效于 "1"。<br/>
* 字符 {}|&~![()" 也不能用在键名的任何地方,而且这些字符在选项值中有着特殊的意义.
* </note>
* true,和false因为会被转义,所以如果希望在解析出的数组中false和true能转变成boolean类型的,则可以给该值加上引号
* <code>
* [filters]
* filter1.isopen='true'
* filter1.isadd=true
* </code>
* 则会解析成:
* <code>
* array(
* 'filters' => array(
* 'isopen' => true,//boolean类型
* 'isadd' => '1', //string 类型
* )
* )
* </code>
*
* @author Qian Su <[email protected]>
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
* @version $Id$
* @package parser
*/
class WindIniParser {
/**
* ini中分割数组的标识
*
* @var string
*/
const ARRAY_SEP = '.';
/**
* 解析数据
*
* @param string $filename ini格式文件
* @param boolean $build 是否解析,默认为true
* @return boolean
*/
public function parse($filename, $build = true) {
if (!is_file($filename)) return array();
$data = parse_ini_file($filename, true);
return $build ? $this->buildData($data) : $data;
}
/**
* 构建数据
*
* @param array $data 将解析出来的数据进行值解析
* @return array 解析后的数组
*/
private function buildData(&$data) {
foreach ((array) $data as $key => $value) {
if (is_array($value)) {
$data[$key] = $this->formatDataArray($value);
} else {
$this->formatDataFromString($key, $value, $data);
}
}
return $data;
}
/**
* 将每行ini文件转换成数组
*
* @param string $key ini文件中的键
* @param string $value ini文件中的值
* @param array $data 操作数据,默认为array()
* @return array
*/
private function toArray($key, $value, &$data = array()) {
if (empty($key)) return array();
if (strpos($key, self::ARRAY_SEP)) {
$start = substr($key, 0, strpos($key, self::ARRAY_SEP));
$end = substr($key, strpos($key, self::ARRAY_SEP) + 1);
$data[$start] = array();
$this->toArray($end, $value, $data[$start]);
} else {
$__tmp = strtolower($value);
$data[$key] = 'false' === $__tmp ? false : ('true' === $__tmp ? true : $value);
}
return $data;
}
/**
* 解析ini格式文件成数组
*
* @param array $original 原始数组
* @param array $data 解析后的数组
* @return array
*/
private function formatDataArray(&$original, &$data = array()) {
foreach ((array) $original as $key => $value) {
$tmp = $this->toArray($key, $value);
foreach ($tmp as $tkey => $tValue) {
if (is_array($tValue)) {
(!isset($data[$tkey])) && $data[$tkey] = array();
$this->formatDataArray($tValue, $data[$tkey]);
} else {
$data[$tkey] = $tValue;
}
}
}
return $data;
}
/**
* 从字符串中合并数组
*
* @param string $key 待合并的键值
* @param string $value 待合并的数据
* @param array $data 操作数组
* @return array
*/
private function formatDataFromString($key, $value, &$data) {
$tmp = $this->toArray($key, $value);
if (false === strpos($key, self::ARRAY_SEP)) return $tmp;
$start = substr($key, 0, strpos($key, self::ARRAY_SEP));
if ((!isset($data[$start]) || !is_array($data[$start])) && isset($tmp[$start])) {
$data[$start] = $tmp[$start];
unset($data[$key]);
return $data;
}
foreach ($data as $d_key => $d_value) {
if (!isset($tmp[$d_key]) || !is_array($tmp[$d_key])) {
continue;
}
foreach ($tmp[$d_key] as $a => $b) {
$this->merge($a, $b, $data[$start]);
}
}
unset($data[$key]);
return $data;
}
/**
* 合并格式化的数组
*
* @param string $key 待合并的键值
* @param mixed $value 待合并的数据
* @param array $data 合并到的数据
* @return array
*/
private function merge($key, $value, &$data = array()) {
if (!is_array($value)) {
$data[$key] = $value;
return $data;
}
$v_key = array_keys($value);
$c_key = $v_key[0];
if (is_array($value[$c_key])) {
$this->merge($c_key, $value[$c_key], $data[$key]);
} else {
$data[$key][$c_key] = $value[$c_key];
}
return $data;
}
}