hyperf控制器不能直接return字符串,需用response()->raw()或json()返回;raw()默认text/html,可链式设content-type;json()自动设application/json并编码数组;注意utf-8编码与header声明。

Hyperf控制器直接 return 字符串会出错
Hyperf 默认不接受裸字符串作为响应体,直接 return 'hello' 会触发 TypeError: Cannot convert object to string 或返回空响应。这是因为 Hyperf 的控制器方法预期返回的是 ResponseInterface 实例(如 Response),而非原始字符串。
用 response()->raw() 返回纯字符串
这是最常用、最轻量的方式,适用于返回 HTML 片段、JSON 字符串、XML、纯文本等无需额外包装的场景:
use Hyperf\HttpServer\Contract\ResponseInterface;
public function index(ResponseInterface $response)
{
return $response->raw('Hello World');
}
-
raw()不做任何内容类型设置,响应头默认为text/html; charset=utf-8 - 如需指定 MIME 类型(比如返回 JSON 字符串但不想走
json()自动编码),可链式调用:$response->raw('{"a":1}')->withHeader('Content-Type', 'application/json') - 注意:如果字符串含中文,确保源码文件是 UTF-8 编码,否则可能乱码
用 response()->json() 返回结构化字符串
当你要返回的是合法 JSON 字符串(且希望自动设好 header 和状态码)时,别手写 raw() + 手动设 Content-Type —— 直接用 json() 更安全:
public function data()
{
return $this->response->json(['code' => 0, 'msg' => 'ok']);
}
-
json()内部调用json_encode(),并自动设置Content-Type: application/json - 若你已有一个 JSON 字符串(比如从缓存读取的
$jsonStr = '{"code":0}'),不要json(json_decode($jsonStr)),而应:raw($jsonStr)->withHeader('Content-Type', 'application/json') - 默认状态码是 200;需要其他码(如 400)可加参数:
json(['error' => 'bad'], 400)
返回字符串时容易忽略的 Header 和编码问题
Hyperf 默认不显式设置 Content-Length,也不强制声明 charset,但某些客户端或代理(如 Nginx + FastCGI)对缺失 charset 的 text/plain 响应会误判编码:
- 返回纯文本建议显式声明:
$response->raw("你好")->withHeader('Content-Type', 'text/plain; charset=utf-8') - 避免用
echo或print输出字符串 —— 这会破坏 Swoole 的协程响应生命周期,导致连接异常或空白响应 - 如果字符串来自外部(如 Redis、数据库字段),确认其编码确实是 UTF-8;PHP 的
mb_detect_encoding()不可靠,建议在入库/存入前统一转码
真正要小心的不是“怎么返回”,而是返回后客户端是否按预期解码 —— 字符串本身没逻辑错误,但 header 缺失或错配会让前端拿到乱码或截断内容。











