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.0.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\Parser\AbstractParser; |
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 extends AbstractParser |
32
|
|
|
{ |
33
|
|
|
/** |
34
|
|
|
* The Env key parser |
35
|
|
|
* |
36
|
|
|
* @var \M1\Env\Parser\KeyParser $key_parser |
37
|
|
|
*/ |
38
|
|
|
private $key_parser; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* The Env value parser |
42
|
|
|
* |
43
|
|
|
* @var \M1\Env\Parser\ValueParser $value_parser |
44
|
|
|
*/ |
45
|
|
|
private $value_parser; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* The parser constructor |
49
|
|
|
* |
50
|
|
|
* @param string $file The .env to parse |
51
|
|
|
* @param bool $origin_exception Whether or not to throw ParseException in the .env |
52
|
|
|
*/ |
53
|
45 |
|
public function __construct($file, $origin_exception = false) |
54
|
|
|
{ |
55
|
45 |
|
parent::__construct($file, $origin_exception); |
56
|
|
|
|
57
|
45 |
|
$this->key_parser = new KeyParser($file, $origin_exception); |
58
|
45 |
|
$this->value_parser = new ValueParser($file, $origin_exception); |
59
|
45 |
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Opens the .env, parses it then returns the contents |
63
|
|
|
* |
64
|
|
|
* @return array The .env contents |
65
|
|
|
*/ |
66
|
45 |
|
public function parse() |
67
|
|
|
{ |
68
|
45 |
|
$raw_content = file($this->file, FILE_IGNORE_NEW_LINES); |
69
|
|
|
|
70
|
45 |
|
if (!$raw_content) { |
|
|
|
|
71
|
3 |
|
return array(); |
72
|
|
|
} |
73
|
|
|
|
74
|
42 |
|
return $this->parseContent($raw_content); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Parses the .env line by line |
79
|
|
|
* |
80
|
|
|
* @param array $raw_content The raw content of the file |
81
|
|
|
* |
82
|
|
|
* @throws \M1\Env\Exception\ParseException If the file does not have a key=value structure |
83
|
|
|
* |
84
|
|
|
* @return array The .env contents |
85
|
|
|
*/ |
86
|
42 |
|
public function parseContent(array $raw_content) |
87
|
|
|
{ |
88
|
42 |
|
$lines = array(); |
89
|
42 |
|
$line_num = 0; |
90
|
|
|
|
91
|
42 |
|
foreach ($raw_content as $raw_line) { |
92
|
42 |
|
$line_num++; |
93
|
|
|
|
94
|
42 |
|
if ($this->startsWith('#', $raw_line) || !$raw_line) { |
95
|
9 |
|
continue; |
96
|
|
|
} |
97
|
|
|
|
98
|
39 |
|
$lines = $this->parseLine($raw_line, $line_num, $lines); |
99
|
27 |
|
} |
100
|
|
|
|
101
|
27 |
|
return $lines; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Parses a line of the .env |
106
|
|
|
* |
107
|
|
|
* @param string $raw_line The raw content of the line |
108
|
|
|
* @param int $line_num The line number of the line |
109
|
|
|
* @param array $lines The parsed lines |
110
|
|
|
* |
111
|
|
|
* @return array The parsed lines |
112
|
|
|
*/ |
113
|
39 |
|
private function parseLine($raw_line, $line_num, $lines) |
114
|
|
|
{ |
115
|
39 |
|
list($key, $value) = $this->parseKeyValue($raw_line, $line_num); |
116
|
|
|
|
117
|
36 |
|
$key = $this->key_parser->parse($key, $line_num); |
118
|
|
|
|
119
|
30 |
|
if (!is_string($key)) { |
120
|
3 |
|
return $lines; |
121
|
|
|
} |
122
|
|
|
|
123
|
30 |
|
$lines[$key] = $this->value_parser->parse($value, $lines, $line_num); |
124
|
|
|
|
125
|
24 |
|
return $lines; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Gets the key = value items from the line |
130
|
|
|
* |
131
|
|
|
* @param string $raw_line The raw content of the line |
132
|
|
|
* @param int $line_num The line number of the line |
133
|
|
|
* |
134
|
|
|
* @throws \M1\Env\Exception\ParseException If the line does not have a key=value structure |
135
|
|
|
* |
136
|
|
|
* @return array The parsed lines |
137
|
|
|
*/ |
138
|
39 |
|
private function parseKeyValue($raw_line, $line_num) |
139
|
|
|
{ |
140
|
39 |
|
$key_value = explode("=", $raw_line, 2); |
141
|
|
|
|
142
|
39 |
|
if (count($key_value) !== 2) { |
143
|
3 |
|
throw new ParseException( |
144
|
3 |
|
'You must have a key = value', |
145
|
3 |
|
$this->origin_exception, |
146
|
3 |
|
$this->file, |
147
|
3 |
|
$raw_line, |
148
|
|
|
$line_num |
149
|
3 |
|
); |
150
|
|
|
} |
151
|
|
|
|
152
|
36 |
|
return $key_value; |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.