【发布时间】:2016-01-21 11:28:29
【问题描述】:
我在 laravel 中有一个资源控制器来管理我的用户。这将创建一个路由来更新用户信息,该路由使用 HTTP PUT 方法接收请求。
这显示了artisan route:list 命令输出:
+--------+--------------------------------+-----------------------------------------------------------+--------------------------------------+--------------------------------------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+--------------------------------+-----------------------------------------------------------+--------------------------------------+--------------------------------------------------------------------------------+------------+
...
| | PUT | users/{users} | users.update | App\Http\Controllers\Users\UsersController@update | auth |
它在我的网络浏览器上正常工作,但是当我尝试使用 codeception 运行测试并提交表单时,我得到一个方法不允许的异常并且测试失败。
我试图了解为什么会发生这种情况,这似乎是 codeception 发出的请求。该请求是使用 POST 而不是 PUT 方法发出的,这会阻止 Laravel 匹配路由。
HTML 表单不支持 PUT 方法,因此 Laravel Form 帮助类创建表单如下:
<form method="POST" action="https://myapp.dev/users/172" accept-charset="UTF-8">
<input name="_method" value="PUT" type="hidden">
...
但是,codeception 似乎没有读取 _method 值。
我该如何解决这个问题?
编辑:深入研究代码,我发现测试不会覆盖请求方法,因为Request 类中的一个常量称为Request::$httpMethodParameterOverride。
/**
* Gets the request "intended" method.
*
* If the X-HTTP-Method-Override header is set, and if the method is a POST,
* then it is used to determine the "real" intended HTTP method.
*
* The _method request parameter can also be used to determine the HTTP method,
* but only if enableHttpMethodParameterOverride() has been called.
*
* The method is always an uppercased string.
*
* @return string The request method
*
* @api
*
* @see getRealMethod()
*/
public function getMethod()
{
if (null === $this->method) {
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
if ('POST' === $this->method) {
if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
$this->method = strtoupper($method);
} elseif (self::$httpMethodParameterOverride) {
$this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
}
}
}
return $this->method;
}
之前的常量值应该是true,但是当我运行测试时,它的值是false。
【问题讨论】:
-
使用 -vv 标志运行测试以查看实际发送的参数。
-
完成。输出显示 Codeception 如何按预期执行带有
_method = PUT属性的POST请求。但不知何故,这与我定义的 PUT 路由不匹配。但是,在 Web 浏览器中执行此操作匹配正确。 -
我在更新处理上有同样的问题。我系统地有一个 404 错误。事实上,更新方法并没有在我的控制器中执行,这导致更新 url 上的代码接收没有在更新方法中处理后应该发生的重定向。自从两周以来我一直在阻止这个问题,但没有找到任何解决方案或找到解决方案的线索。
-
请停止写 Codeception 没有读取 _method 值,您已经确认 _method 在请求中传递。
-
由 Laravel 来解释参数并调用正确的方法。 Codeception 测试套件包括 Laravel5 站点,该站点的测试形式与您的相似,方法设置为 PATCH 并通过:github.com/janhenkgerritsen/codeception-laravel5-sample/blob/…
标签: php forms laravel laravel-5 codeception