答案是access_token、sign、q、error_code这四个字段最易出错:access_token有效期30天且需主动刷新;sign必须用hmacsha256按指定顺序拼接计算;q为明文且长度≤2000字符;error_code需查控制台完整列表。

看不懂百度API文档,先盯死这四个字段
不是文档写得差,是它默认你已经知道“请求体怎么拼、签名怎么算、token怎么续、错误码怎么查”。实际卡住的永远是这四个字段:access_token、sign、q、error_code——其他全是干扰项。
常见错误现象:调用返回 {"error_code":110,"error_msg":"Access token invalid or no longer valid"},但你明明刚拿过 token;或者 {"error_code":28,"error_msg":"invalid sign"},反复核对参数顺序还是失败。
-
access_token不是永久有效的,有效期 30 天,但百度文档里藏在“鉴权说明”二级菜单下,且不提示刷新逻辑 -
sign必须用HmacSHA256算,不是 MD5,不是 SHA1,不是 base64(raw),必须是Base64.encode(HmacSHA256(app_id + q + salt + secret_key)) -
q是待翻译文本,但长度超 2000 字符会直接报错error_code:54000,文档里写在“限制说明”页末尾,字号比正文小两号 -
error_code查表要上百度智能云控制台“帮助中心 → 错误码查询”,官网文档里的错误码列表缺了至少 7 个高频码(比如 110、28、54000)
Symfony 2 项目里别碰 make:controller 直接写
Symfony 2 没有 make:controller 命令,那是 Symfony 4+ 的功能。硬套会导致 Command "make:controller" is not defined,接着去搜“Symfony 2 controller generator”,浪费半小时。
正确做法:手动建控制器,路径固定为 src/Controller/TranslateController.php,类名必须继承 Controller(不是 AbstractController),且不能用 PHP 8 属性路由(#[Route] 不支持)。
- 路由写在
app/config/routing.yml里:translate_api: path: /api/translate defaults: { _controller: AppBundle:Translate:index } - 控制器方法必须返回
Response对象,$this->json()在 Symfony 2.8 之前不存在,要用new Response(json_encode([...]), 200, ['Content-Type' => 'application/json']) - HTTP 客户端别用
guzzlehttp/guzzle6.x+,Symfony 2 默认兼容的是guzzlehttp/guzzle3.x 或原生cURL;装高版本会触发Class GuzzleHttp\Client not found
百度翻译 API 的签名生成,PHP 里最容易漏掉的三件事
签名不对,90% 是因为没按百度原始要求来。不是算法写错,是上下文环境没对齐。
- 拼原料字符串时,
q必须是原始文本,不能提前urlencode(),也不能json_encode()包一层——文档示例里是明文,你就得传明文 -
salt必须是整型时间戳(time()),不是字符串,不是microtime(true),不是随机数;传错类型会导致 HMAC 计算结果全错 - Secret Key 末尾若有换行符(比如从控制台复制时带了
\n),HmacSHA256会把它当有效字符参与计算,签名必然失败;建议用rtrim($secretKey, "\n\r")清洗
Token 刷新必须自己写逻辑,别信“自动续期”
百度的 access_token 有效期 30 天,但接口调用频次高时,实际 2 小时就可能被回收(尤其测试环境)。文档说“token 失效后重新获取”,没告诉你怎么判断失效、怎么缓存、怎么并发防重复刷新。
真实场景中,error_code 为 110 或 111 时才需要刷新,但响应里不带新 token,得再发一次 /oauth/2.0/token 请求。这个过程如果没加锁,高并发下会刷出一堆无效 token,触发配额限流。
- 缓存 token 必须用文件或 APCu(Symfony 2 不支持 Redis 驱动的 cache 组件),键名建议含
app_id和timestamp,避免多应用混用 - 刷新前先检查本地缓存是否过期(
filemtime() ),而不是每次请求都重取 - 并发刷新需加文件锁:
flock($fp, LOCK_EX),否则多个请求同时刷新,后写的覆盖前写的,导致部分请求拿不到有效 token
最麻烦的不是签名或 token,是百度把 q 参数长度限制和 error_code 含义拆在三页不同文档里,还用了两套术语——“请求参数”页叫“query”,“错误码”页叫“text”,调试时得来回切页面对照。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











