百度api返回空数据主因是symfony 2未正确处理http错误:guzzle/curl默认不抛4xx/5xx异常,且未校验状态码、content-type及json解析错误;需在服务层强制校验并包装为symfony标准异常。

百度API返回空数据,不是百度的问题,大概率是 Symfony 2 的异常处理没拦住底层错误,或者你根本没让它抛异常 —— HttpClient 在 Symfony 2 里还不存在,你用的其实是 guzzlehttp/guzzle 或原生 cURL,而它们默认对 4xx/5xx 响应不自动抛异常,空响应往往就是 400/401/403 后被静默吞掉的结果。
为什么 $response->getBody()->getContents() 返回空字符串
常见于百度地图、OCR、翻译等 API 返回非 JSON 错误页(比如 HTML 登录跳转、JSONP 包裹、或纯文本错误提示),但你的代码只调用了 getContents() 却没检查状态码或 Content-Type。
- 百度 API 出错时经常返回
text/html或application/json;charset=UTF-8但内容是{"status":401,"message":"invalid key"}—— 这种 JSON 是合法的,但如果你手动json_decode($content, true)却没判json_last_error(),就可能得到null - 更隐蔽的是 cURL 层级错误:比如 DNS 解析失败、连接超时,
curl_exec()返回false,但没检查curl_errno()就直接json_decode(),结果也是null - Symfony 2 没有
$response->toArray(),别套用新版本写法;你得自己if ($response->getStatusCode() >= 400) { throw new \RuntimeException(...); }
在 Symfony 2 中捕获并转换百度 API 异常的最小可行做法
别依赖控制器里零散的 try/catch,把调用封装进独立服务,并强制校验响应结构。
- 用
GuzzleHttp\Client(推荐 6.x 版本,兼容 PHP 5.6+):构造时设'http_errors' => true,这样 4xx/5xx 会直接抛ClientException或ServerException - 响应体解析前,先断言
in_array($response->getHeaderLine('Content-Type'), ['application/json', 'application/json; charset=utf-8']) - 执行
json_decode($response->getBody()->getContents(), true)后,立刻检查json_last_error() === JSON_ERROR_NONE,否则 throw 新异常,附带原始响应体用于调试 - 百度 API 常见错误字段是
status和message,不要假设它一定有error键;统一提取逻辑放在服务层,别让控制器处理这些分支
如何让 Symfony 2 的 kernel.exception 监听器识别百度 API 异常
Symfony 2 的事件系统支持 kernel.exception,但默认监听器只处理内核抛出的 HttpException 子类,你自定义的 API 异常不会自动进这个链路 —— 必须手动触发。
- 在 API 服务中,把百度异常包装成
Symfony\Component\HttpKernel\Exception\BadRequestHttpException(对应 400)或UnauthorizedHttpException(对应 401),这样内核才能识别并走标准异常流程 - 监听器里不要硬编码
if ($e instanceof \Exception),而是明确判断$e instanceof BadRequestHttpException || $e instanceof UnauthorizedHttpException - 注意:Symfony 2 不支持
getAcceptableContentTypes(),改用$request->headers->get('Accept')并手工解析,比如stripos($accept, 'application/json') !== false - 返回 JSON 响应时,别用
new Response(json_encode(...)),用Symfony\Component\HttpFoundation\JsonResponse,它会自动设Content-Type: application/json
最易被忽略的一点:百度 API 的 ak(Access Key)如果过期或配错,返回的 HTTP 状态码仍是 200,但 body 里是 {"status": 302, "message": "AK invalid"} —— 这种情况必须在业务层主动检查 status 字段,不能只靠 HTTP 状态码。异常处理的边界,永远在你调用 API 的那一层,而不是等它炸到 controller 才反应。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











