当前位置: 首页 > 面试题库 >

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

葛子昂
2023-03-14
问题内容

使用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将处理呈现和交付View。

如果出于某种原因您想跳过默认行为,则可以Cake\Network\Response从具有完整创建的响应的操作中返回一个对象。

*从3.4开始\Cake\Http\Response

食谱 >控制器>控制器动作

配置响应

使用符合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/jsonaccept标头的适当请求。



 类似资料:
  • 本文向大家介绍Laravel实现自定义错误输出内容的方法,包括了Laravel实现自定义错误输出内容的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Laravel实现自定义错误输出内容的方法。分享给大家供大家参考,具体如下: 这里分析一下laravel对于提交的数据进行验证,怎么自定义错误输出的内容 在根目录下运行命令 会在app\Http\Requests目录下创建PostUpda

  • 我有一个gradle构建脚本,它检索了一些常见的依赖项,并将它们组合起来创建了一个“胖罐子”。

  • 我正在尝试从输入提示中获取此人的姓名。获取名称长度,如果长度小于1,则抛出自定义错误抛出LineLimitException,并再次提示用户输入他们的名称。我知道我在这里投入了很多代码,但我希望它能让我想要做的事情更清楚。 LineLimitException类 在这里我提示并存储name字段

  • 因此,基本上,当为时,即第一次,应在20秒内触发,并将设置为。从下一次开始,它应该每隔5秒就会被发射一次。 我面临的问题是,每次被激发时,输出中只有一条消息。也就是说,我在20秒后收到一条消息,每5秒收到一条消息。我希望在每次触发的输出中有20条消息。 如果我使用并创建一个五秒的时间窗口,则每5秒输出20条消息。请帮我把这个代码弄对。我是不是缺了什么?

  • 本文向大家介绍ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法,包括了ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法的使用技巧和注意事项,需要的朋友参考一下 ThinkPHP的conf文件中的Convention.php有一个配置选项 'DEFAULT_FILTER'        =>  'htmlspecialchars', // 默认参数过滤方法 用于I

  • 我见过有人建议使用sys。Python中的exit()。我的问题是,有没有其他方法可以退出当前脚本的执行,我的意思是终止,并出现错误。 大概是这样的: 目前我的解决方案是: