1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the m1\env library |
5
|
|
|
* |
6
|
|
|
* (c) m1 <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
* |
11
|
|
|
* @package m1/env |
12
|
|
|
* @version 1.1.0 |
13
|
|
|
* @author Miles Croxford <[email protected]> |
14
|
|
|
* @copyright Copyright (c) Miles Croxford <[email protected]> |
15
|
|
|
* @license http://github.com/m1/env/blob/master/LICENSE.md |
16
|
|
|
* @link http://github.com/m1/env/blob/master/README.md Documentation |
17
|
|
|
*/ |
18
|
|
|
|
19
|
|
|
namespace M1\Env; |
20
|
|
|
|
21
|
|
|
use M1\Env\Exception\ParseException; |
22
|
|
|
use M1\Env\Helper\StringHelper; |
23
|
|
|
use M1\Env\Parser\ValueParser; |
24
|
|
|
use M1\Env\Parser\KeyParser; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* The .env parser |
28
|
|
|
* |
29
|
|
|
* @since 0.1.0 |
30
|
|
|
*/ |
31
|
|
|
class Parser |
32
|
|
|
{ |
33
|
|
|
/** |
34
|
|
|
* The .env to parse |
35
|
|
|
* |
36
|
|
|
* @var string $file |
37
|
|
|
*/ |
38
|
|
|
public $file; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* The Env key parser |
42
|
|
|
* |
43
|
|
|
* @var \M1\Env\Parser\KeyParser $key_parser |
44
|
|
|
*/ |
45
|
|
|
private $key_parser; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* The line num of the current value |
49
|
|
|
* |
50
|
|
|
* @var int $line_num |
51
|
|
|
*/ |
52
|
|
|
public $line_num; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* The current parsed values/lines |
56
|
|
|
* |
57
|
|
|
* @var array $lines |
58
|
|
|
*/ |
59
|
|
|
public $lines; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* If to throw ParseException in the .env |
63
|
|
|
* |
64
|
|
|
* @var bool $origin_exception |
65
|
|
|
*/ |
66
|
|
|
public $origin_exception; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* The String helper class |
70
|
|
|
* |
71
|
|
|
* @var \M1\Env\Helper\StringHelper $string_helper |
72
|
|
|
*/ |
73
|
|
|
public $string_helper; |
74
|
|
|
|
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* The Env value parser |
78
|
|
|
* |
79
|
|
|
* @var \M1\Env\Parser\ValueParser $value_parser |
80
|
|
|
*/ |
81
|
|
|
public $value_parser; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* The parser constructor |
85
|
|
|
* |
86
|
|
|
* @param string $file The .env to parse |
87
|
|
|
* @param bool $origin_exception Whether or not to throw ParseException in the .env |
88
|
|
|
*/ |
89
|
63 |
|
public function __construct($file, $origin_exception = false) |
90
|
|
|
{ |
91
|
63 |
|
$this->file = $file; |
92
|
63 |
|
$this->origin_exception = $origin_exception; |
93
|
63 |
|
$this->key_parser = new KeyParser($this); |
94
|
63 |
|
$this->value_parser = new ValueParser($this); |
95
|
63 |
|
$this->string_helper = new StringHelper(); |
96
|
63 |
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Opens the .env, parses it then returns the contents |
100
|
|
|
* |
101
|
|
|
* @return array The .env contents |
102
|
|
|
*/ |
103
|
63 |
|
public function parse() |
104
|
|
|
{ |
105
|
63 |
|
$raw_content = file($this->file, FILE_IGNORE_NEW_LINES); |
106
|
|
|
|
107
|
63 |
|
if (empty($raw_content)) { |
108
|
3 |
|
return array(); |
109
|
|
|
} |
110
|
|
|
|
111
|
60 |
|
return $this->parseContent($raw_content); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Parses the .env line by line |
116
|
|
|
* |
117
|
|
|
* @param array $raw_content The raw content of the file |
118
|
|
|
* |
119
|
|
|
* @throws \M1\Env\Exception\ParseException If the file does not have a key=value structure |
120
|
|
|
* |
121
|
|
|
* @return array The .env contents |
122
|
|
|
*/ |
123
|
60 |
|
public function parseContent(array $raw_content) |
124
|
|
|
{ |
125
|
60 |
|
$this->lines = array(); |
126
|
60 |
|
$this->line_num = 0; |
127
|
|
|
|
128
|
60 |
|
foreach ($raw_content as $raw_line) { |
129
|
60 |
|
$this->line_num++; |
130
|
|
|
|
131
|
60 |
|
if ($this->string_helper->startsWith('#', $raw_line) || !$raw_line) { |
132
|
12 |
|
continue; |
133
|
|
|
} |
134
|
|
|
|
135
|
57 |
|
$this->parseLine($raw_line); |
136
|
39 |
|
} |
137
|
|
|
|
138
|
39 |
|
return $this->lines; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Parses a line of the .env |
143
|
|
|
* |
144
|
|
|
* @param string $raw_line The raw content of the line |
145
|
|
|
* |
146
|
|
|
* @return array The parsed lines |
147
|
|
|
*/ |
148
|
57 |
|
private function parseLine($raw_line) |
149
|
|
|
{ |
150
|
57 |
|
$raw_line = $this->parseExport($raw_line); |
151
|
|
|
|
152
|
54 |
|
list($key, $value) = $this->parseKeyValue($raw_line); |
153
|
|
|
|
154
|
51 |
|
$key = $this->key_parser->parse($key); |
155
|
|
|
|
156
|
45 |
|
if (!is_string($key)) { |
157
|
3 |
|
return; |
158
|
|
|
} |
159
|
|
|
|
160
|
45 |
|
$this->lines[$key] = $this->value_parser->parse($value); |
161
|
36 |
|
} |
162
|
|
|
|
163
|
57 |
|
private function parseExport($raw_line) |
164
|
|
|
{ |
165
|
57 |
|
$line = trim($raw_line); |
166
|
|
|
|
167
|
57 |
|
if ($this->string_helper->startsWith("export", $line)) { |
168
|
6 |
|
$export_line = explode("export", $raw_line, 2); |
169
|
|
|
|
170
|
6 |
View Code Duplication |
if (count($export_line) !== 2 || empty($export_line[1])) { |
|
|
|
|
171
|
3 |
|
throw new ParseException( |
172
|
3 |
|
'You must have a export key = value', |
173
|
3 |
|
$this->origin_exception, |
174
|
3 |
|
$this->file, |
175
|
3 |
|
$raw_line, |
176
|
3 |
|
$this->line_num |
177
|
3 |
|
); |
178
|
|
|
} |
179
|
|
|
|
180
|
3 |
|
$line = trim($export_line[1]); |
181
|
3 |
|
} |
182
|
|
|
|
183
|
54 |
|
return $line; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Gets the key = value items from the line |
188
|
|
|
* |
189
|
|
|
* @param string $raw_line The raw content of the line |
190
|
|
|
* |
191
|
|
|
* @throws \M1\Env\Exception\ParseException If the line does not have a key=value structure |
192
|
|
|
* |
193
|
|
|
* @return array The parsed lines |
194
|
|
|
*/ |
195
|
54 |
|
private function parseKeyValue($raw_line) |
196
|
|
|
{ |
197
|
54 |
|
$key_value = explode("=", $raw_line, 2); |
198
|
|
|
|
199
|
54 |
|
if (count($key_value) !== 2) { |
200
|
3 |
|
throw new ParseException( |
201
|
3 |
|
'You must have a key = value', |
202
|
3 |
|
$this->origin_exception, |
203
|
3 |
|
$this->file, |
204
|
3 |
|
$raw_line, |
205
|
3 |
|
$this->line_num |
206
|
3 |
|
); |
207
|
|
|
} |
208
|
|
|
|
209
|
51 |
|
return $key_value; |
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
|
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.