<?php // 禁用输出缓冲 while (ob_get_level()) { ob_end_clean(); } ob_implicit_flush(true); // 禁止 PHP 输出缓冲 // 设置正确的响应头,告知客户端这是一个 SSE 流 header('Content-Type: text/event-stream'); header('Transfer-Encoding: chunked'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); // 目标网址 $targetUrl = 'https://APi.x.ai'; // 目标 URL 替换为实际地址 // 获取原始请求数据 $requestData = file_get_contents('php://input'); // 获取原始请求头 $requestHeaders = getallheaders(); // 构建目标 URL $targetUrl .= $_SERVER['REQUEST_URI']; // 处理查询参数 $queryString = $_SERVER['QUERY_STRING']; if (!empty($queryString)) { $targetUrl .= '?' . $queryString; } // 创建 cURL 句柄 $ch = curl_init(); // 设置 cURL 选项 curl_setopt($ch, CURLOPT_URL, $targetUrl); // 设置目标网址 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 不保存结果,直接输出 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']); // 使用与原始请求相同的方法 curl_setopt($ch, CURLOPT_postFIELDS, $requestData); // 设置请求数据 curl_setopt($ch, CURLOPT_HTTPHEADER, formatRequestHeaders($requestHeaders)); // 设置请求头 // 禁用 ssl 验证 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 不验证对等证书 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 不验证主机名 // 启用调试信息 curl_setopt($ch, CURLOPT_VERBOSE, true); // 设置回调函数,每次接收到数据时都输出 curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) { // 每次接收到的数据都直接输出 //echo $data; // SSE 格式要求以 "data: " 开头,每个事件后加双换行 // 逐字输出数据 $chars = str_split($data); // 将数据按字符分割 foreach ($chars as $char) { echo $char; ob_flush(); // 刷新 PHP 缓冲区 flush(); // 刷新系统输出缓冲区 } //ob_flush(); // 刷新 PHP 缓冲区 //flush(); // 刷新系统输出缓冲区 return strlen($data); // 返回数据长度,告知 cURL 数据已处理 }); // 执行 cURL 请求 $response = curl_exec($ch); // 检查是否有错误发生 if(curl_errno($ch)) { $error = curl_error($ch); http_response_code(500); // 处理错误 echo 'cURL Error: ' . $error; } else { // 获取响应的 HTTP 状态码 $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 设置响应的 HTTP 状态码 http_response_code($httpStatus); } // 关闭 cURL 句柄 curl_close($ch); /** * 格式化请求头,将关联数组转换为字符串数组 * * @param array $headers 关联数组的请求头 * @return array 字符串数组的请求头 */ function formatRequestHeaders($headers) { $formattedHeaders = []; foreach ($headers as $key => $value) { // 可以根据需要调整需要传递的头部字段 if (in_array(strtolower($key), ['authorization', 'content-type'])) { $formattedHeaders[] = $key . ': ' . $value; } } return $formattedHeaders; }
第一个版本:目前有bug就是会等待所有的内容输出完毕后才会输出。暂时可用,将就下吧。
目前这是第二版,已解决第一个版本的bug。
需要配置伪静态
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php$1 last;
}
添加新评论