Skip to content

Commit 7ddfaad

Browse files
committed
opz routes collects
1 parent f07e123 commit 7ddfaad

File tree

4 files changed

+134
-47
lines changed

4 files changed

+134
-47
lines changed

example/tests/compare_exec.php

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,96 @@
11
<?php
22

3+
const ALLOWED_METHODS_STR = 'ANY,GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD';
4+
const ALLOWED_METHODS = [
5+
'ANY',
6+
'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD',
7+
// 'COPY', 'PURGE', 'LINK', 'UNLINK', 'LOCK', 'UNLOCK', 'VIEW', 'SEARCH', 'CONNECT', 'TRACE',
8+
];
9+
310
$times = isset($argv[1]) ? (int)$argv[1] : 1000;
411

5-
$str = '/50be3774f6/{arg1}/arg2/arg3/{int}/arg5/arg6/{arg7}/arg8/arg9[/850726135a]';
12+
// $str = 'get';
13+
$str = ['get', 'post'];
614

7-
$sample1 = function ($path) {
8-
$first = null;
15+
$sample1 = function ($methods) {
16+
$hasAny = false;
17+
$methods = \array_map(function ($m) use (&$hasAny) {
18+
$m = \strtoupper(\trim($m));
919

10-
// eg '/article/12'
11-
if ($pos = \strpos($path, '/', 1)) {
12-
$first = \substr($path, 1, $pos - 1);
13-
}
20+
if (!$m || false === \strpos(ALLOWED_METHODS_STR . ',', $m . ',')) {
21+
throw new \InvalidArgumentException(
22+
"The method [$m] is not supported, Allow: " . ALLOWED_METHODS_STR
23+
);
24+
}
25+
26+
if (!$hasAny && $m === 'ANY') {
27+
$hasAny = true;
28+
}
1429

15-
return $first;
30+
return $m;
31+
}, (array)$methods);
32+
33+
return $hasAny ? ALLOWED_METHODS : $methods;
1634
};
1735

18-
$sample2 = function ($path) {
19-
$first = null;
20-
$path = ltrim($path, '/');
36+
$sample2 = function ($methods) {
37+
if (is_string($methods)) {
38+
$method = strtoupper($methods);
39+
40+
if ($method === 'ANY') {
41+
return ALLOWED_METHODS;
42+
}
43+
44+
if (false === \strpos(ALLOWED_METHODS_STR . ',', $method . ',')) {
45+
throw new \InvalidArgumentException(
46+
"The method [$method] is not supported, Allow: " . ALLOWED_METHODS_STR
47+
);
48+
}
49+
50+
return [$method];
51+
}
52+
53+
$upperMethods = [];
54+
55+
foreach ((array)$methods as $method) {
56+
$method = strtoupper($method);
57+
58+
if ($method === 'ANY') {
59+
return ALLOWED_METHODS;
60+
}
61+
62+
if (false === \strpos(ALLOWED_METHODS_STR . ',', $method . ',')) {
63+
throw new \InvalidArgumentException(
64+
"The method [$method] is not supported, Allow: " . ALLOWED_METHODS_STR
65+
);
66+
}
2167

22-
// eg '/article/12'
23-
if ($pos = \strpos($path, '/')) {
24-
$first = \substr($path, 0, $pos);
68+
$upperMethods[] = $method;
2569
}
2670

27-
return $first;
71+
return $upperMethods;
2872
};
2973

30-
compare_speed($sample1, $sample2, $times, [$str]);
74+
// $sample2 = function ($route, $params) {
75+
// $route = (string)preg_replace_callback('#\{[a-zA-Z_][\w-]*\}#', function ($m) use ($params) {
76+
// //var_dump($m, $params);die;
77+
// $name = substr($m[0], 1, -1);
78+
// return '(' . ($params[$name] ?? '[^/]+') . ')';
79+
// }, $route);
80+
//
81+
// return $route;
82+
// };
83+
84+
compare_speed($sample1, $sample2, $times, [
85+
$str,
86+
[
87+
'all' => '.*',
88+
'any' => '[^/]+', // match any except '/'
89+
'num' => '[1-9][0-9]*', // match a number and gt 0
90+
'int' => '\d+', // match a number
91+
'act' => '[a-zA-Z][\w-]+', // match a action name
92+
]
93+
]);
3194

3295
function compare_speed(callable $sample1, callable $sample2, int $times = 1000, array $args = [])
3396
{

src/Base/AbstractRouter.php

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -385,39 +385,55 @@ public function validateArguments($methods, $handler): array
385385
throw new \InvalidArgumentException('The method and route handler is not allow empty.');
386386
}
387387

388-
$hasAny = false;
389-
$methods = \array_map(function ($m) use (&$hasAny) {
390-
$m = \strtoupper(\trim($m));
388+
if (\is_string($methods)) {
389+
$method = \strtoupper($methods);
391390

392-
if (!$m || false === \strpos(self::ALLOWED_METHODS_STR . ',', $m . ',')) {
391+
if ($method === 'ANY') {
392+
return self::ALLOWED_METHODS;
393+
}
394+
395+
if (false === \strpos(self::ALLOWED_METHODS_STR . ',', $method . ',')) {
393396
throw new \InvalidArgumentException(
394-
"The method [$m] is not supported, Allow: " . self::ALLOWED_METHODS_STR
397+
"The method [$method] is not supported, Allow: " . self::ALLOWED_METHODS_STR
395398
);
396399
}
397400

398-
if (!$hasAny && $m === self::ANY) {
399-
$hasAny = true;
401+
return [$method];
402+
}
403+
404+
$upperMethods = [];
405+
406+
foreach ((array)$methods as $method) {
407+
$method = \strtoupper($method);
408+
409+
if ($method === 'ANY') {
410+
return self::ALLOWED_METHODS;
411+
}
412+
413+
if (false === \strpos(self::ALLOWED_METHODS_STR . ',', $method . ',')) {
414+
throw new \InvalidArgumentException(
415+
"The method [$method] is not supported, Allow: " . self::ALLOWED_METHODS_STR
416+
);
400417
}
401418

402-
return $m;
403-
}, (array)$methods);
419+
$upperMethods[] = $method;
420+
}
404421

405-
return $hasAny ? self::ALLOWED_METHODS : $methods;
422+
return $upperMethods;
406423
}
407424

408425
/**
409426
* parse param route
410-
* @param string $route
411427
* @param array $params
412428
* @param array $conf
413429
* @return array
414430
* @throws \LogicException
415431
*/
416-
public function parseParamRoute(string $route, array $params, array $conf): array
432+
public function parseParamRoute(array $conf, array $params = []): array
417433
{
418-
$first = $noOptional = null;
419-
$backup = $route;
420-
$argPos = \strpos($backup, '{');
434+
$first = null;
435+
$backup = $route = $conf['original'];
436+
$argPos = \strpos($route, '{');
421437

422438
// quote '.','/' to '\.','\/'
423439
if (false !== \strpos($route, '.')) {
@@ -458,7 +474,7 @@ public function parseParamRoute(string $route, array $params, array $conf): arra
458474

459475
$start = \substr($backup, 0, $floorPos);
460476

461-
// 解析参数,替换为对应的 正则
477+
// Parse the parameters and replace them with the corresponding regular
462478
if (\preg_match_all('#\{([a-zA-Z_][\w-]*)\}#', $route, $m)) {
463479
/** @var array[] $m */
464480
$pairs = [];

src/ORouter.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,10 @@ public function map($methods, string $route, $handler, array $opts = []): Abstra
7070
return $this;
7171
}
7272

73+
$conf['original'] = $route;
74+
7375
// collect param route
74-
$this->collectParamRoute($route, $methods, $conf, $opts['params'] ?? []);
76+
$this->collectParamRoute($methods, $conf, $opts['params'] ?? []);
7577

7678
return $this;
7779
}
@@ -120,17 +122,14 @@ protected function prepareForMap(string $route, $handler, array $opts): array
120122
}
121123

122124
/**
123-
* @param string $route
124125
* @param array $methods
125126
* @param array $conf
126127
* @param array $params
127128
* @throws \LogicException
128129
*/
129-
protected function collectParamRoute(string $route, array $methods, array $conf, array $params)
130+
protected function collectParamRoute(array $methods, array $conf, array $params)
130131
{
131-
$conf['original'] = $route;
132-
$params = $this->getAvailableParams($params);
133-
list($first, $conf) = $this->parseParamRoute($route, $params, $conf);
132+
list($first, $conf) = $this->parseParamRoute($conf, $this->getAvailableParams($params));
134133

135134
// route string have regular
136135
if ($first) {

test/AbstractRouterTest.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,51 +46,60 @@ public function testParseParamRoute()
4646
'handler' => 'some_handler'
4747
];
4848

49-
$ret = $stub->parseParamRoute('/im/{name}/{age}', [], $conf);
49+
$conf['original'] = '/im/{name}/{age}';
50+
$ret = $stub->parseParamRoute($conf);
5051
$this->assertCount(2, $ret);
5152
$this->assertEquals('im', $ret[0]);// first node
5253
$this->assertArrayHasKey('start', $ret[1]);
5354
$this->assertEquals('/im/', $ret[1]['start']);
5455

55-
$ret = $stub->parseParamRoute('/path/to/{name}', [], $conf);
56+
$conf['original'] = '/path/to/{name}';
57+
$ret = $stub->parseParamRoute($conf);
5658
$this->assertCount(2, $ret);
5759
$this->assertEquals('path', $ret[0]);
5860
$this->assertArrayHasKey('start', $ret[1]);
5961
$this->assertEquals('/path/to/', $ret[1]['start']);
6062

61-
$ret = $stub->parseParamRoute('/path/to/some/{name}', [], $conf);
63+
$conf['original'] = '/path/to/some/{name}';
64+
$ret = $stub->parseParamRoute($conf);
6265
$this->assertCount(2, $ret);
6366
$this->assertEquals('path', $ret[0]);
6467
$this->assertArrayHasKey('start', $ret[1]);
6568
$this->assertEquals('/path/to/some/', $ret[1]['start']);
6669

67-
$ret = $stub->parseParamRoute('/hi/{name}', [], $conf);
70+
$conf['original'] = '/hi/{name}';
71+
$ret = $stub->parseParamRoute($conf);
6872
$this->assertCount(2, $ret);
6973
$this->assertEquals('hi', $ret[0]);
7074
$this->assertArrayHasKey('start', $ret[1]);
7175

72-
$ret = $stub->parseParamRoute('/hi[/{name}]', [], $conf);
76+
$conf['original'] = '/hi[/{name}]';
77+
$ret = $stub->parseParamRoute($conf);
7378
$this->assertNull($ret[0]);
7479
$this->assertArrayHasKey('start', $ret[1]);
7580
$this->assertEquals('/hi', $ret[1]['start']);
7681

77-
$ret = $stub->parseParamRoute('/hi[/tom]', [], $conf);
82+
$conf['original'] = '/hi[/tom]';
83+
$ret = $stub->parseParamRoute($conf);
7884
$this->assertNull($ret[0]);
7985
$this->assertArrayHasKey('start', $ret[1]);
8086
$this->assertEquals('/hi', $ret[1]['start']);
8187

82-
$ret = $stub->parseParamRoute('/hi/[tom]', [], $conf);
88+
$conf['original'] = '/hi/[tom]';
89+
$ret = $stub->parseParamRoute($conf);
8390
$this->assertEquals('hi', $ret[0]);
8491
$this->assertArrayHasKey('start', $ret[1]);
8592
$this->assertEquals('/hi/', $ret[1]['start']);
8693

87-
$ret = $stub->parseParamRoute('/{category}', [], $conf);
94+
$conf['original'] = '/{category}';
95+
$ret = $stub->parseParamRoute($conf);
8896
$this->assertNull($ret[0]);
8997
$this->assertNull($ret[1]['start']);
9098
$this->assertArrayHasKey('start', $ret[1]);
9199
$this->assertEquals(null, $ret[1]['start']);
92100

93-
$ret = $stub->parseParamRoute('/blog-{category}', [], $conf);
101+
$conf['original'] = '/blog-{category}';
102+
$ret = $stub->parseParamRoute($conf);
94103
$this->assertNull($ret[0]);
95104
$this->assertEquals('/blog-', $ret[1]['start']);
96105
$this->assertArrayHasKey('start', $ret[1]);

0 commit comments

Comments
 (0)