rya*_*txr 3 php cakephp httpresponse cakephp-3.x cakephp-3.4
使用CakePHP 3.4,PHP 7.0.
我正在尝试使用一个非常简单的控制器方法来输出一些JSON.它输出"无法修改标题...".
public function test() {
$this->autoRender = false;
echo json_encode(['method' => __METHOD__, 'class' => get_called_class()]);
}
Run Code Online (Sandbox Code Playgroud)
浏览器输出
{"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 ...)
Run Code Online (Sandbox Code Playgroud)
我完全理解为什么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
$content = json_encode(['method' => __METHOD__, 'class' => get_called_class()]);
$this->response = $this->response->withStringBody($content);
$this->response = $this->response->withType('json');
// ...
return $this->response;
Run Code Online (Sandbox Code Playgroud)
对PSR-7兼容的接口使用不可改变的方法,的返回值的因而利用率withStringBody()和withType().在CakePHP <3.4.3中,withStringBody()不可用,您可以直接写入正文流,这不会改变响应对象的状态:
$this->response->getBody()->write($content);
Run Code Online (Sandbox Code Playgroud)
$content = json_encode(['method' => __METHOD__, 'class' => get_called_class()]);
$this->response->body($content);
$this->response->type('json');
// ...
return $this->response;
Run Code Online (Sandbox Code Playgroud)
$content = ['method' => __METHOD__, 'class' => get_called_class()];
$this->set('content', $content);
$this->set('_serialize', 'content');
Run Code Online (Sandbox Code Playgroud)
这还需要使用请求处理程序组件,并启用扩展解析和使用.json附加的响应URL ,或发送带有application/jsonaccept头的正确请求.