修复了一个错字,我认为应该禁用整个路由资源,但只禁用带有通配符的uri


Fixed a typo that I thought should disable an entire route resource but only disables URIs with a wildcard

简单的博客crud应用程序,添加了标签功能,目前所有路由都运行良好。索引和创建页面正在渲染,新标签存储良好,但当我试图击中编辑页面(/admin/tag/1/edit)时,Laravel抛出

NotFoundHttpException in RouteCollection.php line 161

我检查我的路由:列表,它看起来很好,Firebug只是给出一个基本的404没有找到GET app.dev/admin/tag/1/edit。最后,我注意到标签路径上有一个斜杠:

$router->group([
    'namespace' => 'Admin',
    'middleware' => 'auth',
    ], function () {
    resource('admin/post', 'PostController');
    resource('admin/tag/', 'TagController');
});

改成

    resource('admin/tag', 'TagController');

,现在编辑页面渲染得很好。

最后我意识到这也发生在任何带有通配符{$id}(销毁、编辑、显示、更新)的URI上。所以我的问题是为什么。为什么非通配符uri可以正常工作,而其他uri不行?

在这种情况下,您需要在路由组中使用prefix:

$router->group([
  'prefix' => 'admin',  // <= prefix
  'namespace' => 'Admin',
  'middleware' => 'auth',      
  ], function () {
  resource('post', 'PostController'); // <= changes , eq. admin/post
  resource('tag', 'TagController');  // <= changes , eq. admin/tag
});

关于"尾斜杠"。我想,它只与资源路由有关。你错误地使用它路由组。在此之前,请查看文档中关于资源控制器处理的操作。

然后,如果你看'vendor'laravel'framework'src'Illuminate'Routing'ResourceRegistrar.php,你可以看到行:

   protected $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy'];

然后查看方法'register':

    public function register($name, $controller, array $options = [])
{
    // If the resource name contains a slash, we will assume the developer wishes to
    // register these resource routes with a prefix so we will set that up out of
    // the box so they don't have to mess with it. Otherwise, we will continue.
    if (Str::contains($name, '/')) {
        $this->prefixedResource($name, $controller, $options);
        return;
    }
    // We need to extract the base resource from the resource name. Nested resources
    // are supported in the framework, but we need to know what name to use for a
    // place-holder on the route wildcards, which should be the base resources.
    $base = $this->getResourceWildcard(last(explode('.', $name)));
    $defaults = $this->resourceDefaults;
    foreach ($this->getResourceMethods($defaults, $options) as $m) {
        $this->{'addResource'.ucfirst($m)}($name, $base, $controller, $options);
    }
}

您的admin/tag/正在经历这个条件:

if (Str::contains($name, '/')) { /*...*/ }

我没有陷入更深(你可以自己做),但我假设在explode/implode中99%的问题(当"尾斜杠"存在时-参见资源控制器处理的动作的定义)=>路由器可以解决创建或索引的动作,但不能解决编辑等。(我们得到404)