1 | <?php |
||
23 | class Matcher |
||
24 | { |
||
25 | |||
26 | /** |
||
27 | * @var Collector |
||
28 | */ |
||
29 | |||
30 | protected $collector; |
||
31 | |||
32 | /** |
||
33 | * @var Parser $parser |
||
34 | */ |
||
35 | |||
36 | protected $parser; |
||
37 | |||
38 | /** |
||
39 | * Define a basepath to all routes. |
||
40 | * |
||
41 | * @var string |
||
42 | */ |
||
43 | |||
44 | protected $basepath = ""; |
||
45 | |||
46 | /** |
||
47 | * Construct the route dispatcher. |
||
48 | * |
||
49 | * @param Collector $collector |
||
50 | * @param string $basepath Define a Path prefix that must be excluded on matches. |
||
51 | */ |
||
52 | |||
53 | 54 | public function __construct(Collector $collector, $basepath = "") |
|
54 | { |
||
55 | 54 | $this->collector = $collector; |
|
56 | 54 | $this->basepath = $basepath; |
|
57 | 54 | } |
|
58 | |||
59 | /** |
||
60 | * Find a route that matches the given arguments. |
||
61 | * |
||
62 | * @param string $httpMethod |
||
63 | * @param string $path |
||
64 | * |
||
65 | * @throws NotFoundException |
||
66 | * @throws MethodNotAllowedException |
||
67 | * |
||
68 | * @return Route |
||
69 | */ |
||
70 | |||
71 | 48 | public function match($httpMethod, $path) |
|
72 | { |
||
73 | 48 | $path = $this->parsePath($path); |
|
74 | 48 | $route = null; |
|
|
|||
75 | |||
76 | 48 | if (!$route = $this->collector->findStaticRoute($httpMethod, $path)) { |
|
77 | 35 | if (!$route = $this->matchDynamicRoute($httpMethod, $path)) { |
|
78 | 14 | $this->matchSimilarRoute($httpMethod, $path); |
|
79 | } |
||
80 | 27 | } |
|
81 | |||
82 | 42 | $route->setMatcher($this); |
|
83 | 42 | return $route; |
|
84 | } |
||
85 | |||
86 | /** |
||
87 | * Find and return the request dynamic route based on the compiled data and Path. |
||
88 | * |
||
89 | * @param string $httpMethod |
||
90 | * @param string $path |
||
91 | * |
||
92 | * @return Route|false If the request match an array with the action and parameters will |
||
93 | * be returned otherwise a false will. |
||
94 | */ |
||
95 | |||
96 | 35 | protected function matchDynamicRoute($httpMethod, $path) |
|
97 | { |
||
98 | 35 | if ($routes = $this->collector->findDynamicRoutes($httpMethod, $path)) { |
|
99 | // cache the parser reference |
||
100 | 29 | $this->parser = $this->collector->getParser(); |
|
101 | // chunk routes for smaller regex groups using the Sturges' Formula |
||
102 | 29 | foreach (array_chunk($routes, round(1 + 3.3 * log(count($routes))), true) as $chunk) { |
|
103 | 29 | array_map([$this, "buildRoute"], $chunk); |
|
104 | 29 | list($pattern, $map) = $this->buildGroup($chunk); |
|
105 | |||
106 | 29 | if (!preg_match($pattern, $path, $matches)) { |
|
107 | 7 | continue; |
|
108 | } |
||
109 | |||
110 | /** @var Route $route */ |
||
111 | 27 | $route = $map[count($matches)]; |
|
112 | 27 | unset($matches[0]); |
|
113 | |||
114 | 27 | $route->setParams(array_combine($route->getParams(), array_filter($matches))); |
|
115 | |||
116 | 27 | return $route; |
|
117 | 7 | } |
|
118 | 7 | } |
|
119 | |||
120 | 14 | return false; |
|
121 | } |
||
122 | |||
123 | /** |
||
124 | * Parse the dynamic segments of the pattern and replace then for |
||
125 | * corresponding regex. |
||
126 | * |
||
127 | * @param Route $route |
||
128 | * @return Route |
||
129 | */ |
||
130 | |||
131 | 29 | protected function buildRoute(Route $route) |
|
140 | |||
141 | /** |
||
142 | * Group several dynamic routes patterns into one big regex and maps |
||
143 | * the routes to the pattern positions in the big regex. |
||
144 | * |
||
145 | * @param Route[] $routes |
||
146 | * @return array |
||
147 | */ |
||
148 | |||
149 | 29 | protected function buildGroup(array $routes) |
|
163 | |||
164 | /** |
||
165 | * Parse an route pattern seeking for parameters and build the route regex. |
||
166 | * |
||
167 | * @param string $pattern |
||
168 | * @return array 0 => new route regex, 1 => map of parameter names |
||
169 | */ |
||
170 | |||
171 | 29 | protected function parsePlaceholders($pattern) |
|
185 | |||
186 | /** |
||
187 | * Get only the path of a given url. |
||
188 | * |
||
189 | * @param string $path The given URL |
||
190 | * |
||
191 | * @throws Exception |
||
192 | * @return string |
||
193 | */ |
||
194 | |||
195 | 48 | protected function parsePath($path) |
|
205 | |||
206 | /** |
||
207 | * Generate an HTTP error request with method not allowed or not found. |
||
208 | * |
||
209 | * @param string $httpMethod |
||
210 | * @param string $path |
||
211 | * |
||
212 | * @throws NotFoundException |
||
213 | * @throws MethodNotAllowedException |
||
214 | */ |
||
215 | |||
216 | 14 | protected function matchSimilarRoute($httpMethod, $path) |
|
227 | |||
228 | /** |
||
229 | * Verify if a static route match in another method than the requested. |
||
230 | * |
||
231 | * @param string $targetHttpMethod The HTTP method that must not be checked |
||
232 | * @param string $path The Path that must be matched. |
||
233 | * |
||
234 | * @return array |
||
235 | */ |
||
236 | |||
237 | 14 | protected function checkStaticRouteInOtherMethods($targetHttpMethod, $path) |
|
243 | |||
244 | /** |
||
245 | * Verify if a dynamic route match in another method than the requested. |
||
246 | * |
||
247 | * @param string $targetHttpMethod The HTTP method that must not be checked |
||
248 | * @param string $path The Path that must be matched. |
||
249 | * |
||
250 | * @return array |
||
251 | */ |
||
252 | |||
253 | protected function checkDynamicRouteInOtherMethods($targetHttpMethod, $path) |
||
259 | |||
260 | /** |
||
261 | * Strip the given http methods and return all the others. |
||
262 | * |
||
263 | * @param string|string[] |
||
264 | * @return array |
||
265 | */ |
||
266 | |||
267 | 14 | protected function getHttpMethodsBut($targetHttpMethod) |
|
271 | |||
272 | /** |
||
273 | * @return Collector |
||
274 | */ |
||
275 | |||
276 | public function getCollector() |
||
280 | |||
281 | /** |
||
282 | * @return string |
||
283 | */ |
||
284 | |||
285 | 1 | public function getBasePath() |
|
289 | |||
290 | /** |
||
291 | * Set a new basepath, this will be a prefix that must be excluded in |
||
292 | * every requested Path. |
||
293 | * |
||
294 | * @param string $basepath The new basepath |
||
295 | */ |
||
296 | |||
297 | 1 | public function setBasePath($basepath) |
|
301 | |||
302 | } |
||
303 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.