查一天了,用echo可以实时打印,但却是打印在控制台上,想要正常返回只能用
$this->response()->write();,但这玩意死活不能流式响应
查了一天,文档上根本没写,还是看response里的代码才发现这个属性
setIsChunk
最后其实核心三行代码就可以实现:
$this->response()->withHeader('Transfer-Encoding', 'chunked'); $this->response()->setIsChunk(true); $this->response()->write(urlencode($text));
设置个响应头,在设置个setIsChunk属性,然后就能流式响应了
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $data) {
// 按data:分割为数组
$dataArr = explode('data:', $data);
// 处理每个数据块
foreach ($dataArr as $chunk) {
// 如果数据块为空则跳过
if (!$chunk) {
continue;
}
// 将数据块解析为json
$jsonData = json_decode($chunk);
//isset非空判断,属性不存在则返回false
if (isset($jsonData->choices)&&isset($jsonData->choices[0]->delta->content)){
$text=$jsonData->choices[0]->delta->content;
$this->response()->withHeader('Transfer-Encoding', 'chunked');
$this->response()->setIsChunk(true);
$this->response()->write(urlencode($text));
}
}
return strlen($data);
});