【问题标题】:How do you specify an HTTP status code in Cakephp?如何在 Cakephp 中指定 HTTP 状态码?
【发布时间】:2010-11-09 05:00:30
【问题描述】:

在我的控制器中,我检查一个条件以查看是否允许用户做某事。如果检查失败,我想将 403 发送回浏览器。我如何在 Cakephp 中做到这一点?

【问题讨论】:

  • 另外值得注意的是,CakePHP 3x 符合PSR-7

标签: cakephp


【解决方案1】:

EDIT - 这个问题很老了,涵盖了不同版本的 CakePHP 框架。以下是每个答案适用于哪个版本的摘要。不要忘记对最有帮助的解决方案进行投票。

EDIT #2 - Mark37 添加了用于 CakePHP 2.x 的 more detailed answer

EDIT #3 - 添加了 CakePHP 的解决方案。 (2018 年 5 月:CakePHP 3.5 做了一些函数重命名,solution by Roberto 仍然有效。)


通过查看上一条评论中的相关API code,您似乎可以调用Controller::header($status) 来输出标头而无需重定向。在您的情况下,最有可能正确使用:

$this->header('HTTP/1.1 403 Forbidden');

【讨论】:

  • 另外,上面的代码只输出标题,所以你可能想用return falsedieexit或类似的东西结束执行。
  • 这比我的回答更准确地回答了这个问题。尽管如此,我认为在这种情况下能够将用户重定向到自定义页面还是很有用的,它比空白的“服务器响应此”页面要好。
  • 查看该方法的主体,它似乎是一个名为 header 的内置函数的包装器。
  • 由于所有 cakephp 实际上都是更多的 php,实际上大多数东西都可以归结为“内置函数的包装器”。这个想法是通过包装简化了您的开发,并且性能开销可以忽略不计。
  • 我的意思是,header() 是在 PHP 中发送 http 标头的标准方法,但您确实问过“我如何使用 CakePHP 来做到这一点”,我认为这意味着“我'将使用 Cake 提供的东西'。
【解决方案2】:
$this->response->statusCode(403);

将在 Cake 准备好发送响应时设置状态码。 CakeResponse::send() 期望发送状态码和消息,所以在我的测试中,我认为我的使用 header() 被覆盖了。使用 $this->header('HTTP/1.1 400 Bad Request') 也不起作用,因为 Cake 期望对 $this->header 的任何调用都以冒号分隔:$this->header('Location: ...')

【讨论】:

  • +1 表示 CakePHP 2.x 答案 ($this->response->...),这可能有助于来自 Google 等的当前访问者。(对于那些访问者:2009 年的答案适用于 CakePHP 1.x 代码库)
  • 这会起作用,但是对于 CakePHP 2 中的这些类型的情况,异常往往是首选。它们会立即中止控制器执行,并触发 cake 的标准错误处理过程。
  • 异常对于 4xx 和 5xx 状态更好,但是如果您需要(例如)将 201 返回到 POST 请求,这可能是要走的路。
【解决方案3】:

在 CakePHP 2 中,preferred methodthrow an exception

throw new ForbiddenException();

【讨论】:

  • 它适用于cakephp 3.6,但此代码未使用error403.ctp 模板。如何从ForbiddenException()设置error403.ctp模板
【解决方案4】:

关于 CakePHP 3.x 的注释似乎丢失了,所以为了完成这个线程:

对于 CakePHP 3.x 和 4.x 使用:

$response = $this->response->withStatus(403);
return $response;

对于 CakePHP 3.3.x 之前的版本,您可以使用与 CakePHP 2.x 相同的样式:

$this->response->statusCode('code');

请注意,直接使用 PHP 函数 (http_response_code(403); die();) 也可以,尽管使用 response object 似乎是预期的方法。

【讨论】:

  • return $this->response->withStatus(403); 也适用于 CakePHP 4.x:api.cakephp.org/4.1/class-Cake.Http.Response.html#withStatus
  • 有什么想法可以发送 403 和 json 数据吗?我正在使用 $this->response->statusCode('403');和 $this->set(compact('data')); $this->set('_serialize', ['data']);在我更新到 v 3.9 之前它运行良好
  • 您可以尝试强制使用视图或模板。当您返回错误状态时,ErrorController 可能会启动。
【解决方案5】:

我在这里加两分钱,因为我觉得这些答案中的任何一个都没有像我希望的那样彻底涵盖这个主题(至少对于 Cake 2.x)。

如果您想抛出错误状态,请使用异常类(如其他答案中所述):

throw new BadRequestException(); // 400 Bad Request

// Or customize the code...
throw new BadRequestException('Custom error message', 405); // 405 Method Not Allowed

有趣的事实:即使是通过 ExceptionRenderer 类的 RESTful 调用,Cake 也会自动进行一些神奇的错误渲染。更有趣的事实是它基于状态码,而不是Exception 可能被抛出的事实,所以如果你自己将状态码设置为> 400,你会即使您不想要它们,也可能会收到错误消息。

如果您想为 REST JSON/XML 端点返回特定状态代码,请利用新的 CakeResponse 对象,但还要确保添加特殊的 _serialize 变量,否则您最终会得到一个“未找到视图”错误,因为 cake 将尝试找到一个视图来呈现您的 JSON/XML。 (这是设计使然 - 请参阅 JsonView/XmlView 类。)

$this->response->setStatus(201);  // 201 Created
$this->set('_serialize', array()); // Value must be something other than null

最后,如果您想为定期呈现的页面发送非 200 状态,您可以只使用 setStatus() 方法,如上一个答案中所述:

$this->response->setStatus(201);

更新:

$this->response->setStatus('code');

不再可用。使用

$this->response->statusCode('code');

【讨论】:

  • +1 - 我在上面接受的答案中添加了指向您答案的链接。
  • CakeRequest 在任何 2.x 版本中都没有 setStatus。如果你想在 2.x 中设置状态码,你应该使用CakeResponsestatus 方法。它需要您要设置的状态码的整数版本。
  • 谢谢@BlakeHair - 我想当我最初写这篇文章时,我的意思是写response,但输入了request
  • 使用 _serialize 变量对我不起作用。在使用$this->response->statusCode() 设置状态码后,我必须添加return $this->response。我正在使用 Cake 2.4.5。
【解决方案6】:

在重新审视这个问题并阅读 Adriano 对我之前的回答(关于将用户重定向到友好页面)的评论后,我想出了一个新的解决方案。

在控制器中,您可以调用 $this->cakeError('error404') 来生成友好的 404 页面。这可以通过在“app/views/errors/error404.ctp”创建文件来自定义(与其他错误一样)。

在仔细查看code for cakeError 之后,我的建议是尝试通过在“app/error.php”或(可能更优选)“app/app_error.php”处创建一个文件来扩展 Cake 的 ErrorHandler

error403(模仿error404 code)的代码如下:

class AppError extends ErrorHandler {
    function error403($params) {
        extract($params, EXTR_OVERWRITE);
        $this->error(array(
            'code' => '403',
            'name' => 'Forbidden',
            'message' => sprintf(__("Access was forbidden to the requested address %s on this server.", true), $url, $message)));
            $this->_stop();
     }
}

应该还可以通过创建“app/views/errors/error403.ctp”来为此错误提供自定义视图。这是error404 view的修改版:

<h2><?php echo $name; ?></h2>
<p class="error">
    <strong>Error: </strong>
    <?php echo sprintf(__("Access was forbidden to the requested address %s on this server.", true), "<strong>'{$message}'</strong>")?>
</p>

【讨论】:

  • 好答案!这是我不知道你可以用 Cake 做的一件事。
【解决方案7】:

自 CakePHP 3.6 以来又发生了变化:

立即使用

    $this->setResponse($this->response->withStatus(403) );
    return $this->response; // use this line also 

而不是

    $response = $this->response->withStatus(403);

https://api.cakephp.org/3.7/class-Cake.Controller.Controller.html#_setResponse

【讨论】:

【解决方案8】:

也许in this section of the cakephp manual 可以帮到你。

重定向(字符串 $url,整数 $status, 布尔值 $exit)

您将使用的流量控制方法 最常见的是redirect()。这种方法 采用形式的第一个参数 CakePHP 的相对 URL。当一个用户 已成功下单,您 可能希望将它们重定向到 收据屏幕。第二个参数 redirect() 允许你定义一个 伴随的 HTTP 状态码 重定向。您可能想使用 301 (永久移动)或 303(见 其他),取决于的性质 重定向。

该方法将在之后发出一个 exit() 除非您设置第三个重定向 参数为 false。

【讨论】:

  • 但我不想发回 3xx 状态码。即使这样可行,它似乎也是错误的。
  • 你可以发回任何状态码,303只是一个例子。
  • 这非常适合 3xx 重定向状态代码。对于其他所有事情来说绝对是一个可怕的想法,比如用户的 403。
【解决方案9】:

您可以使用 cakephp response 自定义消息:

$this->response->header('HTTP/1.0 201', 'custom message');
$this->response->send();

【讨论】:

    【解决方案10】:

    核心 PHP link 代码在 cakePHP 中工作。

    header('HTTP/1.1 403 Forbidden');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 2012-07-01
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 2019-09-18
      相关资源
      最近更新 更多