调通豆包api需用curl手动发json请求,带bearer鉴权头和content-type头;model必须为控制台生成的ep-开头服务id;禁用stream避免php阻塞;须解析响应体error字段而非仅看http状态码。

用 cURL 调通豆包 API 的最小可行代码
豆包(Doubao)官方不提供 PHP SDK,必须手动构造 HTTP 请求。核心是调通 /v1/chat/completions 接口,且必须带 Authorization: Bearer {token} 和 Content-Type: application/json。
- Token 从「字节跳动开放平台」控制台申请,不是网页登录 Cookie,也不是飞书 token
- 请求体必须是 JSON 字符串,不能用
http_build_query()拼成表单格式,否则返回400 Bad Request - 必须显式设置
CURLOPT_HTTPHEADER,漏掉Content-Type会返回415 Unsupported Media Type - 示例片段:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://ark.cn-beijing.volces.com/api/v1/chat/completions'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ 'model' => 'ep-20241127160919-2yq8d', 'messages' => [['role' => 'user', 'content' => '你好']] ])); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch);
模型 ID 不是固定字符串,得去控制台实时查
豆包的 model 参数不是写死的 dashscope-qwen-max 这类通用名,而是以 ep- 开头的部署实例 ID,形如 ep-20241127160919-2yq8d。这个 ID 每次在控制台创建「推理服务」时生成,且有效期有限。
- 控制台路径:字节跳动开放平台 → 我的应用 → 选择应用 → 「模型服务」→ 「创建服务」→ 部署成功后复制「服务 ID」
- 直接填错 ID 会返回
404 Not Found或400 Invalid model,不是鉴权失败 - 别复用别人文档里的 ID,每个账号、每个环境都不同
- 如果只做测试,选「免费试用」档位即可,但注意配额耗尽后接口会返回
429 Too Many Requests
stream=true 时 PHP 处理 SSE 流容易卡死
豆包支持流式响应(stream=true),但 PHP 默认的 curl_exec() 是阻塞式等待完整响应,没法边收边处理。强行设 CURLOPT_WRITEFUNCTION 解析 SSE 事件,稍有不慎就丢帧或解析错 data: 前缀。
- 不建议在 Web 请求中开启
stream:PHP-FPM 进程会长时间占用,Nginx 可能超时断连 - 真要流式,推荐用
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 30000)加硬超时,并在WRITEFUNCTION里检查是否收到event: message和完整data: {...} - 更稳妥的做法是关掉流式,等完整 JSON 返回后再
json_decode($response, true),从['choices'][0]['message']['content']取结果 - 注意:流式响应的 JSON 结构和非流式完全不同,不能混用解析逻辑
错误码不是全靠 curl_error() 捕获
很多报错实际是 HTTP 成功(200)但业务层失败,比如 token 过期、配额用完、输入超长——这些都返回 200 OK + JSON 错误体,curl_error() 完全捕获不到。
- 必须检查响应体是否含
'error'字段:if (isset($decoded['error'])) { echo $decoded['error']['message']; } - 典型业务错误:
"error": {"code": "InvalidAPIKey", "message": "Invalid API key"}(密钥错)、"code": "RequestEntityTooLarge"(输入 > 32k 字符) - 别只看
curl_getinfo($ch, CURLINFO_HTTP_CODE)是不是 200,401和429确实会返回,但多数问题藏在 200 体里 - 调试时先用
file_get_contents('php://input')打印原始响应体,比猜错误类型快得多
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











