CakePHP 3使资源路由可以使用和不使用参数

时间:2017-11-27 22:02:42

标签: php rest cakephp cakephp-3.0

我的路线文件中有一些代码:

Router::scope('/v1', function (RouteBuilder $routes) {
    $routes->resources( 'Files');
});

然后是一个带有删除功能的FilesController,如:

public function delete($id){
    echo "here"; exit();
}

当我这样做时:

DELETE http://192.168.1.197/v1/files/1

答案是here,但是,如果我这样做:

DELETE http://192.168.1.197/v1/files

响应是它缺少V1Controller。

我期望的是CakePHP可以转过来说“哎呀,你传递了错误数量的必需参数”。

这里有一些非常奇怪的东西,我不太确定是什么。如何让两者做同样的事情并指向控制器?

2 个答案:

答案 0 :(得分:2)

启用调试模式时,CakePHP对异常的操作方式有很大不同。当调试为true时,将使用调试信息,堆栈跟踪和开发人员友好消息呈现所有异常。

当调试模式为false时,异常将呈现为标准HTTP响应类型。带有400和500错误代码的句柄。

当路由器找不到路由匹配时,不涉及控制器。 HTTP请求永远不会超过调度阶段。它是调度程序抛出400类型的异常。

在您给出的示例中,框架正在抛出MissingControllerException,其HTTP代码为404

通过ErrorController呈现400个错误代码。 CakePHP带有一个默认的错误控制器,但是如果你使用编辑器模板生成一个新的应用程序,那么你的应用程序控制器持有者应该有一个默认的ErrorController

在模板中应该有一个src/Template/Error/error400.ctp文件,显示400个代码的响应。请记住,启用调试模式时不使用此模板。

您可以修改此模板以找到"密切关注"匹配路由并将其作为建议提供给用户,作为错误消息中的反馈。

您可以像这样轻松迭代所有已配置的路径:

    foreach (Router::routes() as $route) {
        $name = isset($route->options['_name']) ? $route->options['_name'] : $route->getName();
        $output[] = [$name, $route->template, json_encode($route->defaults)];
    }

以上取自cakephp / src / Shell / RoutesShell.php

因为这在技术上是404错误。没有匹配的路线,你可以做的是尝试找到"关闭"一场比赛。这里的问题是您遇到与路由器类相同的路由匹配挑战。

Router类使用动态路由技术,这些技术接收部分URL参数并将其作为控制器名称,操作名称和用户定义参数填充。

这可能会显着改变 ,具体取决于您使用的默认路由器类型。

例如,您可能正在使用执行以下操作的DashedRoute路由类:

/**
 * This route class will transparently inflect the controller, action and plugin
 * routing parameters, so that requesting `/my-plugin/my-controller/my-action`
 * is parsed as `['plugin' => 'MyPlugin', 'controller' => 'MyController', 'action' => 'myAction']`
 */
class DashedRoute extends Route

您可能会使用执行以下操作的InflectedRoute路由类:

/**
 * This route class will transparently inflect the controller and plugin routing
 * parameters, so that requesting `/my_controller` is parsed as `['controller' => 'MyController']`
 */
class InflectedRoute extends Route

由于存在路由可能使用动态路由的情况。无法知道URL段是控制器,操作还是命名参数。

再加上您还使用名为/v1的范围段的复杂性,预测目标路线变得更具挑战性。

您可以创建自定义路由来捕获这些边缘情况并呈现信息性错误消息,也可以尝试向error400.ctp添加逻辑以显示更具信息性的错误消息。

还有一个最终选项。 CakePHP允许您编写自己的自定义Route类,和/或使用您自己的调度程序修改中间件。

答案 1 :(得分:0)

我完全解决了这个问题,只是停止使用CakePHP中的资源路径;我将代码更改为:

$routes->get('/files/*', ['controller' => 'Files', 'action' => 'view'], 'files:get');
$routes->post('/files', ['controller' => 'Files', 'action' => 'add'], 'files:post');
$routes->put('/files/*', ['controller' => 'Files', 'action' => 'edit'], 'files:put');
$routes->patch('/files/*', ['controller' => 'Files', 'action' => 'view'], 'files:patch');
$routes->delete('/files/*', ['controller' => 'Files', 'action' => 'delete'], 'files:delete');

它完全按照我想要的方式运作......