1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Indigo\Ini; |
4
|
|
|
|
5
|
|
|
use Indigo\Ini\Exception\ParserException; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Parses an INI string. |
9
|
|
|
* |
10
|
|
|
* @author Márk Sági-Kazár <[email protected]> |
11
|
|
|
*/ |
12
|
|
|
class Parser |
13
|
|
|
{ |
14
|
|
|
/** |
15
|
|
|
* Parses an INI string. |
16
|
|
|
* |
17
|
|
|
* @param string $ini |
18
|
|
|
* |
19
|
|
|
* @return array |
20
|
|
|
*/ |
21
|
9 |
|
public function parse($ini) |
22
|
|
|
{ |
23
|
9 |
|
if (!is_string($ini)) { |
24
|
1 |
|
throw new ParserException('Cannot parse non-string INI data'); |
25
|
|
|
} |
26
|
|
|
|
27
|
8 |
|
$scannerMode = defined('INI_SCANNER_TYPED') ? INI_SCANNER_TYPED : INI_SCANNER_NORMAL; |
28
|
|
|
|
29
|
8 |
|
$parsedIni = @parse_ini_string($ini, true, $scannerMode); |
30
|
|
|
|
31
|
8 |
|
if (false === $parsedIni) { |
32
|
|
|
$e = error_get_last(); |
33
|
|
|
throw new ParserException('Error during parsing INI: '.$e['message']); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
// Prior to 5.6.1 we have to do some internal parsing as well |
37
|
8 |
|
if (false === defined('INI_SCANNER_TYPED')) { |
38
|
|
|
// We cannot use INI_SCANNER_RAW by default because it is buggy under PHP 5.3.14 and 5.4.4 |
39
|
|
|
// http://3v4l.org/m24cT |
40
|
8 |
|
$rawIni = @parse_ini_string($ini, true, INI_SCANNER_RAW); |
41
|
|
|
|
42
|
8 |
|
$parsedIni = $this->normalize($parsedIni, $rawIni); |
43
|
8 |
|
} |
44
|
|
|
|
45
|
8 |
|
return $parsedIni; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Normalizes INI and array values. |
50
|
|
|
* |
51
|
|
|
* @param $value |
52
|
|
|
* @param $rawValue |
53
|
|
|
* |
54
|
|
|
* @return bool|int|null|string|array |
55
|
|
|
*/ |
56
|
8 |
|
protected function normalize($value, $rawValue) |
57
|
|
|
{ |
58
|
|
|
// Normalize array values |
59
|
8 |
|
if (is_array($value)) { |
60
|
8 |
|
foreach ($value as $i => &$subValue) { |
61
|
8 |
|
$subValue = $this->normalize($subValue, $rawValue[$i]); |
62
|
8 |
|
} |
63
|
|
|
|
64
|
8 |
|
return $value; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
// Don't normalize non-string value |
68
|
8 |
|
if (!is_string($value)) { |
69
|
|
|
return $value; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
// Normalize true boolean value |
73
|
|
View Code Duplication |
if ($value === '1' |
|
|
|
|
74
|
8 |
|
&& (strcasecmp($rawValue, 'true') === 0 |
75
|
4 |
|
|| strcasecmp($rawValue, 'yes') === 0 |
76
|
3 |
|
|| strcasecmp($rawValue, 'on') === 0) |
77
|
8 |
|
) { |
78
|
4 |
|
return true; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
// Normalize false boolean value |
82
|
|
View Code Duplication |
if ($value === '' |
|
|
|
|
83
|
8 |
|
&& (strcasecmp($rawValue, 'false') === 0 |
84
|
4 |
|
|| strcasecmp($rawValue, 'no') === 0 |
85
|
4 |
|
|| strcasecmp($rawValue, 'off') === 0) |
86
|
8 |
|
) { |
87
|
4 |
|
return false; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
// Normalize null value |
91
|
5 |
|
if ($value === '' && strcasecmp($rawValue, 'null') === 0) { |
92
|
1 |
|
return null; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
// Normalize numeric value |
96
|
5 |
|
if (is_numeric($value) && ((string) ($value + 0) === $value)) { |
97
|
|
|
return $value + 0; |
|
|
|
|
98
|
|
|
} |
99
|
|
|
|
100
|
5 |
|
return $value; |
|
|
|
|
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.