PHP 项目即使不安装第三方 SDK,也能用 cURL 从服务端向 OpenAI Responses API 发送 JSON。关键是密钥从服务器环境读取、检查 HTTP 状态,并从 output 消息里提取 output_text,不能把整个 JSON 当成已经解析好的回答。
确认 PHP 环境
在服务器上确认已启用 cURL 扩展,运行 php -m 能看到 curl。设置仅服务端可见的 OPENAI_API_KEY;网页模板、JavaScript、公开仓库和错误页面都不能出现密钥。官方快速入门给出 HTTPS Bearer 认证与 /v1/responses 请求格式。

发送请求并检查响应
保存为 ask.php,在命令行运行 php ask.php。这个示例使用固定输入,不接收未经校验的访客参数。
<?php
declare(strict_types=1);
$key = getenv('OPENAI_API_KEY');
if (!$key) { throw new RuntimeException('服务器缺少 OPENAI_API_KEY'); }
$payload = json_encode([
'model' => 'gpt-6-luna',
'input' => '用一句话解释向量检索。',
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
$curl = curl_init('https://api.openai.com/v1/responses');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $key,
'Content-Type: application/json',
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$raw = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$transportError = curl_error($curl);
curl_close($curl);
if ($raw === false) { throw new RuntimeException('网络传输失败:' . $transportError); }
$data = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($status < 200 || $status >= 300) {
$code = $data['error']['code'] ?? 'unknown';
throw new RuntimeException("API 失败,HTTP $status,错误码 $code");
}
$parts = [];
foreach (($data['output'] ?? []) as $item) {
if (($item['type'] ?? '') !== 'message') { continue; }
foreach (($item['content'] ?? []) as $block) {
if (($block['type'] ?? '') === 'output_text') { $parts[] = $block['text'] ?? ''; }
}
}
$answer = trim(implode("\n", $parts));
if ($answer === '') { throw new RuntimeException('响应成功,但没有可显示的文本'); }
echo $answer, PHP_EOL;
Responses API 迁移说明展示了响应中可能出现多种 output 项目;因此代码只收集消息里的文字块。若你的请求启用工具,不能假设第一个 output 就是最终回答。调试 401、429 等错误时保留状态与错误码,避免打印原始请求头。
验证与边界
正常输出应是一句解释。删除环境变量后应明确报错;使用无权限密钥应看到 HTTP 失败而不是空白。如果站点没有启用 PHP cURL 扩展,先修复服务端环境。这里没有做用户鉴权、限流或历史消息管理;接入公网网站前必须在自己的后端补上。本文依据 2026 年 10 月 1 日官方请求格式编写,尚未在你的 PHP 版本和账号上实测。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31296.html