8000 [Routing] Optimised dumped router matcher, prevent unneeded function … · symfony/symfony@dd647ff · GitHub
[go: up one dir, main page]

Skip to content

Commit dd647ff

Browse files
frankdejongefabpot
authored andcommitted
[Routing] Optimised dumped router matcher, prevent unneeded function calls.
1 parent e58be70 commit dd647ff

File tree

6 files changed

+278
-70
lines changed

6 files changed

+278
-70
lines changed

src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,16 @@ public function match(\$pathinfo)
105105
{
106106
\$allow = array();
107107
\$pathinfo = rawurldecode(\$pathinfo);
108+
\$trimmedPathinfo = rtrim(\$pathinfo, '/');
108109
\$context = \$this->context;
109110
\$request = \$this->request;
111+
\$requestMethod = \$canonicalMethod = \$context->getMethod();
112+
\$scheme = \$context->getScheme();
113+
114+
if ('HEAD' === \$requestMethod) {
115+
\$canonicalMethod = 'GET';
116+
}
117+
110118
111119
$code
112120
@@ -133,7 +141,7 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
133141
foreach ($groups as $collection) {
134142
if (null !== $regex = $collection->getAttribute('host_regex')) {
135143
if (!$fetchedHost) {
136-
$code .= " \$host = \$this->context->getHost();\n\n";
144+
$code .= " \$host = \$context->getHost();\n\n";
137145
$fetchedHost = true;
138146
}
139147

@@ -217,20 +225,15 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
217225
$hostMatches = false;
218226
$methods = $route->getMethods();
219227

220-
// GET and HEAD are equivalent
221-
if (in_array('GET', $methods) && !in_array('HEAD', $methods)) {
222-
$methods[] = 'HEAD';
223-
}
224-
225228
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods));
226229
$regex = $compiledRoute->getRegex();
227230

228231
if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#'.(substr($regex, -1) === 'u' ? 'u' : ''), $regex, $m)) {
229232
if ($supportsTrailingSlash && substr($m['url'], -1) === '/') {
230-
$conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
233+
$conditions[] = sprintf('%s === $trimmedPathinfo', var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
231234
$hasTrailingSlash = true;
232235
} else {
233-
$conditions[] = sprintf('$pathinfo === %s', var_export(str_replace('\\', '', $m['url']), true));
236+
$conditions[] = sprintf('%s === $pathinfo', var_export(str_replace('\\', '', $m['url']), true));
234237
}
235238
} else {
236239
if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() !== $parentPrefix) {
@@ -263,26 +266,57 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
263266
EOF;
264267

265268
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
269+
266270
if ($methods) {
267271
if (1 === count($methods)) {
268-
$code .= <<<EOF
269-
if (\$this->context->getMethod() != '$methods[0]') {
272+
if ($methods[0] === 'HEAD') {
273+
$code .= <<<EOF
274+
if ('HEAD' !== \$requestMethod) {
275+
\$allow[] = 'HEAD';
276+
goto $gotoname;
277+
}
278+
279+
280+
EOF;
281+
} else {
282+
$code .= <<<EOF
283+
if ('$methods[0]' !== \$canonicalMethod) {
270284
\$allow[] = '$methods[0]';
271285
goto $gotoname;
272286
}
273287
274288
275289
EOF;
290+
}
276291
} else {
277-
$methods = implode("', '", $methods);
278-
$code .= <<<EOF
279-
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
292+
$methodVariable = 'requestMethod';
293+
294+
if (in_array('GET', $methods)) {
295+
// Since we treat HEAD requests like GET requests we don't need to match it.
296+
$methodVariable = 'canonicalMethod';
297+
$methods = array_filter($methods, function ($method) { return 'HEAD' !== $method; });
298+
}
299+
300+
if (1 === count($methods)) {
301+
$code .= <<<EOF
302+
if ('$methods[0]' !== \$$methodVariable) {
303+
\$allow[] = '$methods[0]';
304+
goto $gotoname;
305+
}
306+
307+
308+
EOF;
309+
} else {
310+
$methods = implode("', '", $methods);
311+
$code .= <<<EOF
312+
if (!in_array(\$$methodVariable, array('$methods'))) {
280313
\$allow = array_merge(\$allow, array('$methods'));
281314
goto $gotoname;
282315
}
283316
284317
285318
EOF;
319+
}
286320
}
287321
}
288322

@@ -303,7 +337,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
303337
$schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
304338
$code .= <<<EOF
305339
\$requiredSchemes = $schemes;
306-
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
340+
if (!isset(\$requiredSchemes[\$scheme])) {
307341
return \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes));
308342
}
309343

src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ public function match($pathinfo)
2424
{
2525
$allow = array();
2626
$pathinfo = rawurldecode($pathinfo);
27+
$trimmedPathinfo = rtrim($pathinfo, '/');
2728
$context = $this->context;
2829
$request = $this->request;
30+
$requestMethod = $canonicalMethod = $context->getMethod();
31+
$scheme = $context->getScheme();
32+
33+
if ('HEAD' === $requestMethod) {
34+
$canonicalMethod = 'GET';
35+
}
36+
2937

3038
// foo
3139
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
@@ -35,8 +43,8 @@ public function match($pathinfo)
3543
if (0 === strpos($pathinfo, '/bar')) {
3644
// bar
3745
if (preg_match('#^/bar/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
38-
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
39-
$allow = array_merge($allow, array('GET', 'HEAD'));
46+
if ('GET' !== $canonicalMethod) {
47+
$allow[] = 'GET';
4048
goto not_bar;
4149
}
4250

@@ -46,8 +54,8 @@ public function match($pathinfo)
4654

4755
// barhead
4856
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
49-
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
50-
$allow = array_merge($allow, array('GET', 'HEAD'));
57+
if ('GET' !== $canonicalMethod) {
58+
$allow[] = 'GET';
5159
goto not_barhead;
5260
}
5361

@@ -60,17 +68,17 @@ public function match($pathinfo)
6068
if (0 === strpos($pathinfo, '/test')) {
6169
if (0 === strpos($pathinfo, '/test/baz')) {
6270
// baz
63-
if ($pathinfo === '/test/baz') {
71+
if ('/test/baz' === $pathinfo) {
6472
return array('_route' => 'baz');
6573
}
6674

6775
// baz2
68-
if ($pathinfo === '/test/baz.html') {
76+
if ('/test/baz.html' === $pathinfo) {
6977
return array('_route' => 'baz2');
7078
}
7179

7280
// baz3
73-
if ($pathinfo === '/test/baz3/') {
81+
if ('/test/baz3/' === $pathinfo) {
7482
return array('_route' => 'baz3');
7583
}
7684

@@ -83,7 +91,7 @@ public function match($pathinfo)
8391

8492
// baz5
8593
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
86-
if ($this->context->getMethod() != 'POST') {
94+
if ('POST' !== $canonicalMethod) {
8795
$allow[] = 'POST';
8896
goto not_baz5;
8997
}
@@ -94,7 +102,7 @@ public function match($pathinfo)
94102

95103
// baz.baz6
96104
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
97-
if ($this->context->getMethod() != 'PUT') {
105+
if ('PUT' !== $canonicalMethod) {
98106
$allow[] = 'PUT';
99107
goto not_bazbaz6;
100108
}
@@ -106,7 +114,7 @@ public function match($pathinfo)
106114
}
107115

108116
// foofoo
109-
if ($pathinfo === '/foofoo') {
117+
if (< 10000 span class="pl-s">'/foofoo' === $pathinfo) {
110118
return array ( 'def' => 'test', '_route' => 'foofoo',);
111119
}
112120

@@ -116,7 +124,7 @@ public function match($pathinfo)
116124
}
117125

118126
// space
119-
if ($pathinfo === '/spa ce') {
127+
if ('/spa ce' === $pathinfo) {
120128
return array('_route' => 'space');
121129
}
122130

@@ -161,12 +169,12 @@ public function match($pathinfo)
161169
}
162170

163171
// overridden2
164-
if ($pathinfo === '/multi/new') {
172+
if ('/multi/new' === $pathinfo) {
165173
return array('_route' => 'overridden2');
166174
}
167175

168176
// hey
169-
if ($pathinfo === '/multi/hey/') {
177+
if ('/multi/hey/' === $pathinfo) {
170178
return array('_route' => 'hey');
171179
}
172180

@@ -184,7 +192,7 @@ public function match($pathinfo)
184192

185193
if (0 === strpos($pathinfo, '/aba')) {
186194
// ababa
187-
if ($pathinfo === '/ababa') {
195+
if ('/ababa' === $pathinfo) {
188196
return array('_route' => 'ababa');
189197
}
190198

@@ -195,59 +203,59 @@ public function match($pathinfo)
195203

196204
}
197205

198-
$host = $this->context->getHost();
206+
$host = $context->getHost();
199207

200208
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
201209
// route1
202-
if ($pathinfo === '/route1') {
210+
if ('/route1' === $pathinfo) {
203211
return array('_route' => 'route1');
204212
}
205213

206214
// route2
207-
if ($pathinfo === '/c2/route2') {
215+
if ('/c2/route2' === $pathinfo) {
208216
return array('_route' => 'route2');
209217
}
210218

211219
}
212220

213221
if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) {
214222
// route3
215-
if ($pathinfo === '/c2/route3') {
223+
if ('/c2/route3' === $pathinfo) {
216224
return array('_route' => 'route3');
217225
}
218226

219227
}
220228

221229
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
222230
// route4
223-
if ($pathinfo === '/route4') {
231+
if ('/route4' === $pathinfo) {
224232
return array('_route' => 'route4');
225233
}
226234

227235
}
228236

229237
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
230238
// route5
231-
if ($pathinfo === '/route5') {
239+
if ('/route5' === $pathinfo) {
232240
return array('_route' => 'route5');
233241
}
234242

235243
}
236244

237245
// route6
238-
if ($pathinfo === '/route6') {
246+
if ('/route6' === $pathinfo) {
239247
return array('_route' => 'route6');
240248
}
241249

242250
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) {
243251
if (0 === strpos($pathinfo, '/route1')) {
244252
// route11
245-
if ($pathinfo === '/route11') {
253+
if ('/route11' === $pathinfo) {
246254
return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
247255
}
248256

249257
// route12
250-
if ($pathinfo === '/route12') {
258+
if ('/route12' === $pathinfo) {
251259
return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
252260
}
253261

@@ -280,15 +288,15 @@ public function match($pathinfo)
280288
}
281289

282290
// route17
283-
if ($pathinfo === '/route17') {
291+
if ('/route17' === $pathinfo) {
284292
return array('_route' => 'route17');
285293
}
286294

287295
}
288296

289297
if (0 === strpos($pathinfo, '/a')) {
290298
// a
291-
if ($pathinfo === '/a/a...') {
299+
if ('/a/a...' === $pathinfo) {
292300
return array('_route' => 'a');
293301
}
294302

0 commit comments

Comments
 (0)
0