>我正在阅读一篇有关参数化中间件的文章,而我在想参数的奇怪语法。它看起来像是静态方法调用中的错字,someclass :: class。’:: somemethod’。
如果该参数比字符串更复杂,例如基本枚举。
进入水
,所以我查看了中间件方法的代码。
/**
* get or set the middlewares attached to the route.
*
* @param array|string|null $middleware
* @return $this|array
*/
public function middleware($middleware = null)
{
if (is_null($middleware)) {
return (array) ($this->action['middleware'] ?? []);
}
if (! is_array($middleware)) {
$middleware = func_get_args();
}
foreach ($middleware as $index => $value) {
$middleware[$index] = (string) $value;
}
$this->action['middleware'] = array_merge(
(array) ($this->action['middleware'] ?? []), $middleware
);
return $this;
}
登录后复制
>这向我表明,无论您添加到方法中的任何参数,中间件定义总是会转换为字符串。
为什么这会发生?
>
戴上氧气罐和潜水口罩
>我打开了xdebug,并在中间件类手柄方法中添加了一个断点。当我浏览呼叫堆栈时,我找到了创建管道的路由器runroutewithinstack方法。
return (new pipeline($this->container))
->send($request)
->through($middleware)
->then(fn ($request) => $this->prepareresponse(
$request, $route->run()
));
登录后复制
在添加的中间件上循环的管道类循环的当时方法。
public function then(closure $destination)
{
$pipeline = array_reduce(
array_reverse($this->pipes()), $this->carry(), $this->preparedestination($destination)
);
return $pipeline($this->passable);
}
登录后复制
>在随身携带方法中,有一项检查允许类和参数的拆分。
} elseif (! is_object($pipe)) {
[$name, $parameters] = $this->parsepipestring($pipe);
// if the pipe is a string we will parse the string and resolve the class out
// of the dependency injection container. we can then build a callable and
// execute the pipe function giving in the parameters that are required.
$pipe = $this->getcontainer()->make($name);
$parameters = array_merge([$passable, $stack], $parameters);
}
登录后复制
,所以现在我们到达了进行实际分裂的方法,parsepipestring。
protected function parsepipestring($pipe)
{
[$name, $parameters] = array_pad(explode(':', $pipe, 2), 2, []);
if (is_string($parameters)) {
$parameters = explode(',', $parameters);
}
return [$name, $parameters];
}
登录后复制
>这种方法带来的额外条件是参数是用逗号识别的。因此,someclass :: class。’:[a,b]’将导致[‘[a”,’b]’]。
在这次潜水中,我找到了三个地方,在三个地方执行了字符串类型
>
路由中间件方法
管道携带方法,因为它隐含地期望字符串
- 管道parsepipestring方法
-
回到干燥的土地上
- 如果中间件方法确实接受了类似;
的类别怎么办
final readonly class pipelineclass {
public function __constructor(public string $class, public mixed $options) {
$this->validate($class);
}
private function validate(string $class) {
if(!is_callable($class)) {
throw new exception("$class is not callable.");
}
}
}
登录后复制
在管道携带方法中
if (is_callable($pipe)) {
// code
} elseif (! is_object($pipe)) {
// code
} else {
// code
}
登录后复制
>
if($pipe instanceof PipelineClass){
// code
} elseif (is_callable($pipe)) {
// code
} elseif (is_string($pipe)) {
// code
} else {
// code
}
登录后复制
在代码中还有其他几个地方检查了类和参数语法。因此他们也需要更改。
我想知道参数语法是否足以容纳使用该功能的人,还是创建自己的参数语法以使提供更多信息成为可能?
以上就是Laravel参数化中间件深入潜水的详细内容,更多请关注php中文网其它相关文章!