1 | <?php |
||
27 | class UriParser |
||
28 | { |
||
29 | use HostIpTrait; |
||
30 | |||
31 | use HostnameTrait; |
||
32 | |||
33 | use UriBuilderTrait; |
||
34 | |||
35 | use ValidatorTrait; |
||
36 | |||
37 | const REGEXP_URI = ',^ |
||
38 | ((?<scheme>[^:/?\#]+):)? # URI scheme component |
||
39 | (?<authority>//([^/?\#]*))? # URI authority part |
||
40 | (?<path>[^?\#]*) # URI path component |
||
41 | (?<query>\?([^\#]*))? # URI query component |
||
42 | (?<fragment>\#(.*))? # URI fragment component |
||
43 | ,x'; |
||
44 | |||
45 | const REGEXP_AUTHORITY = ',^(?<userinfo>(?<ucontent>.*?)@)?(?<hostname>.*?)?$,'; |
||
46 | |||
47 | const REGEXP_REVERSE_HOSTNAME = ',^((?<port>[^(\[\])]*):)?(?<host>.*)?$,'; |
||
48 | |||
49 | const REGEXP_SCHEME = ',^([a-z]([-a-z0-9+.]+)?)?$,i'; |
||
50 | |||
51 | const REGEXP_INVALID_USER = ',[/?#@:],'; |
||
52 | |||
53 | const REGEXP_INVALID_PASS = ',[/?#@],'; |
||
54 | |||
55 | |||
56 | /** |
||
57 | * Parse a string as an URI according to the regexp form rfc3986 |
||
58 | * |
||
59 | * @param string $uri |
||
60 | * |
||
61 | * @return array |
||
62 | */ |
||
63 | 692 | public function parse($uri) |
|
64 | { |
||
65 | 692 | $parts = $this->extractUriParts($uri); |
|
66 | |||
67 | 692 | return $this->normalizeUriHash(array_merge( |
|
68 | 692 | $this->parseAuthority($parts['authority']), |
|
69 | [ |
||
70 | 680 | 'scheme' => '' === $parts['scheme'] ? null : $parts['scheme'], |
|
71 | 680 | 'path' => $parts['path'], |
|
72 | 680 | 'query' => '' === $parts['query'] ? null : mb_substr($parts['query'], 1, null, 'UTF-8'), |
|
73 | 680 | 'fragment' => '' === $parts['fragment'] ? null : mb_substr($parts['fragment'], 1, null, 'UTF-8'), |
|
74 | ] |
||
75 | 453 | )); |
|
76 | } |
||
77 | |||
78 | /** |
||
79 | * Parse a string as an URI according to the regexp form rfc3986 |
||
80 | * |
||
81 | * @see UriParser::parse |
||
82 | * |
||
83 | * @param string $uri The URI to parse |
||
84 | * |
||
85 | * @return array the array is similar to PHP's parse_url hash response |
||
86 | */ |
||
87 | 692 | public function __invoke($uri) |
|
88 | { |
||
89 | 692 | return $this->parse($uri); |
|
90 | } |
||
91 | |||
92 | /** |
||
93 | * Extract URI parts |
||
94 | * |
||
95 | * @see http://tools.ietf.org/html/rfc3986#appendix-B |
||
96 | * |
||
97 | * @param string $uri The URI to split |
||
98 | * |
||
99 | * @return string[] |
||
100 | */ |
||
101 | 692 | protected function extractUriParts($uri) |
|
116 | |||
117 | /** |
||
118 | * Parse a URI authority part into its components |
||
119 | * |
||
120 | * @param string $authority |
||
121 | * |
||
122 | * @return array |
||
123 | */ |
||
124 | 692 | protected function parseAuthority($authority) |
|
144 | |||
145 | /** |
||
146 | * Parse the hostname into its components Host and Port |
||
147 | * |
||
148 | * No validation is done on the port or host component found |
||
149 | * |
||
150 | * @param string $hostname |
||
151 | * |
||
152 | * @return array |
||
153 | */ |
||
154 | 554 | protected function parseHostname($hostname) |
|
167 | |||
168 | /** |
||
169 | * validate the host component |
||
170 | * |
||
171 | * @param string $host |
||
172 | * |
||
173 | * @return string |
||
174 | */ |
||
175 | 554 | protected function filterHost($host) |
|
183 | |||
184 | /** |
||
185 | * @inheritdoc |
||
186 | */ |
||
187 | 539 | protected function setIsAbsolute($host) |
|
191 | |||
192 | /** |
||
193 | * @inheritdoc |
||
194 | */ |
||
195 | 539 | protected function assertLabelsCount(array $labels) |
|
201 | } |
||
202 |