Parser.php
4.09 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
<?php
namespace Dotenv;
use Dotenv\Exception\InvalidFileException;
class Parser
{
const INITIAL_STATE = 0;
const QUOTED_STATE = 1;
const ESCAPE_STATE = 2;
const WHITESPACE_STATE = 3;
const COMMENT_STATE = 4;
/**
* Parse the given variable name.
*
* @param string $name
*
* @return string
*/
public static function parseName($name)
{
return trim(str_replace(array('export ', '\'', '"'), '', $name));
}
/**
* Parse the given variable value.
*
* @param string $value
*
* @throws \Dotenv\Exception\InvalidFileException
*
* @return string
*/
public static function parseValue($value)
{
if ($value === '') {
return '';
} elseif ($value[0] === '"' || $value[0] === '\'') {
return Parser::parseQuotedValue($value);
} else {
return Parser::parseUnquotedValue($value);
}
}
/**
* Parse the given quoted value.
*
* @param string $value
*
* @throws \Dotenv\Exception\InvalidFileException
*
* @return string
*/
public static function parseQuotedValue($value)
{
$result = array_reduce(str_split($value), function ($data, $char) use ($value) {
switch ($data[1]) {
case Parser::INITIAL_STATE:
if ($char === '"' || $char === '\'') {
return array($data[0], Parser::QUOTED_STATE);
} else {
throw new InvalidFileException(
'Expected the value to start with a quote.'
);
}
case Parser::QUOTED_STATE:
if ($char === $value[0]) {
return array($data[0], Parser::WHITESPACE_STATE);
} elseif ($char === '\\') {
return array($data[0], Parser::ESCAPE_STATE);
} else {
return array($data[0].$char, Parser::QUOTED_STATE);
}
case Parser::ESCAPE_STATE:
if ($char === $value[0] || $char === '\\') {
return array($data[0].$char, Parser::QUOTED_STATE);
} else {
return array($data[0].'\\'.$char, Parser::QUOTED_STATE);
}
case Parser::WHITESPACE_STATE:
if ($char === '#') {
return array($data[0], Parser::COMMENT_STATE);
} elseif (!ctype_space($char)) {
throw new InvalidFileException(
'Dotenv values containing spaces must be surrounded by quotes.'
);
} else {
return array($data[0], Parser::WHITESPACE_STATE);
}
case Parser::COMMENT_STATE:
return array($data[0], Parser::COMMENT_STATE);
}
}, array('', Parser::INITIAL_STATE));
if ($result[1] === Parser::QUOTED_STATE || $result[1] === Parser::ESCAPE_STATE) {
throw new InvalidFileException(
'Dotenv values starting with a quote must finish with a closing quote.'
);
}
return trim($result[0]);
}
/**
* Parse the given unquoted value.
*
* @param string $value
*
* @throws \Dotenv\Exception\InvalidFileException
*
* @return string
*/
public static function parseUnquotedValue($value)
{
$parts = explode(' #', $value, 2);
$value = trim($parts[0]);
// Unquoted values cannot contain whitespace
if (preg_match('/\s+/', $value) > 0) {
// Check if value is a comment (usually triggered when empty value with comment)
if (preg_match('/^#/', $value) > 0) {
$value = '';
} else {
throw new InvalidFileException('Dotenv values containing spaces must be surrounded by quotes.');
}
}
return trim($value);
}
}