繁体   English   中英

如何使用CakePHP 3.4输出自定义HTTP正文内容?回声导致“无法发出标头”错误

[英]How to output custom HTTP body contents with CakePHP 3.4? Echoing causes “Unable to emit headers” error

使用CakePHP 3.4,PHP 7.0。

我正在尝试使用一个非常简单的控制器方法来输出一些JSON。 它输出“无法修改标题...”。

public function test() {
    $this->autoRender = false;
    echo json_encode(['method' => __METHOD__, 'class' => get_called_class()]);
}

浏览器输出

{"method":"App\\Controller\\SomeController::test", "class":"App\\Controller\\SomeController"}

Warning (512): Unable to emit headers. Headers sent in file=...
Warning (2): Cannot modify header information - headers already sent by (output started at ...)
Warning (2): Cannot modify header information - headers already sent by (output started at ...)

我完全理解为什么PHP抱怨这个。 问题是为什么CakePHP会抱怨我该怎么办?

应该注意的是,CakePHP 2.x允许这样做。

控制器永远不应该回显数据! 回应数据可能会导致各种问题,从测试环境中未识别的数据到无法发送的标头,甚至数据被切断。

这样做在CakePHP 2.x中已经是错误的,即使它可能在某些情况下工作,甚至可能在大多数情况下工作。 随着新HTTP堆栈的引入,CakePHP现在在回显响应之前显式检查发送的报头,并相应地触发错误。

发送自定义输出的正确方法是配置和返回响应对象,或使用序列化视图,它在3.x中仍然相同。

从文档引用:

控制器操作通常使用Controller::set()来创建View用于呈现视图层的上下文。 由于CakePHP使用的约定,您无需手动创建和呈现视图。 相反,一旦控制器操作完成,CakePHP将处理渲染并提供视图。

如果由于某种原因您想跳过默认行为,则可以使用完全创建的响应从操作返回Cake\\Network\\Response对象。

*截至3.4,将是\\Cake\\Http\\Response

Cookbook>控制器>控制器操作

配置响应

使用PSR-7兼容接口

$content = json_encode(['method' => __METHOD__, 'class' => get_called_class()]);

$this->response = $this->response->withStringBody($content);
$this->response = $this->response->withType('json');
// ...

return $this->response;

符合PSR-7的接口使用不可变方法,因此利用withStringBody()withType()的返回值。 在CakePHP <3.4.3中, withStringBody()不可用,您可以直接写入正文流,这不会改变响应对象的状态:

$this->response->getBody()->write($content);

使用不推荐使用的界面

$content = json_encode(['method' => __METHOD__, 'class' => get_called_class()]);

$this->response->body($content);
$this->response->type('json');
// ...

return $this->response;

使用序列化视图

$content = ['method' => __METHOD__, 'class' => get_called_class()];

$this->set('content', $content);
$this->set('_serialize', 'content');

这还需要使用请求处理程序组件,并启用扩展解析和使用附加了.json响应URL,或者使用application/json accept标头发送正确的请求。

也可以看看

CakePHP 3有一些叫做JSON视图的东西,允许你返回JSON数据。 我之前没有做任何CakePHP,所以我不知道请求的生命周期,但值得研究。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM