我的路线文件中有一些代码:
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可以转过来说“哎呀,你传递了错误数量的必需参数”。
这里有一些非常奇怪的东西,我不太确定是什么。如何让两者做同样的事情并指向控制器?
答案 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');
它完全按照我想要的方式运作......