Laravel HttpClient调用外部API出现空引用错误求助
背景信息
我正在测试一个外部API,控制器的index方法已成功获取Token及订单列表数据,代码如下:
public function index() { $response = Http::post('http://example.com/authenticate', [ 'Username' => 'ADMIN', 'Password' => 'ADMIN', 'Token' => 'FK98DL-...', ]); $token = json_decode($response, true); $apiURL = 'http://example.com/api/Order/'; $headers = [ 'Content-Type' => 'application/json', 'Authorization' => $token, ]; $response2 = Http::withHeaders($headers)->get($apiURL); $data = $response2->json(); return view('api.auth.orders.index',compact ('data')); }
但实现单个订单详情的show方法时,出现错误:
Object reference not set to an instance of an object.
show方法代码:
public function show($DocNo) { $response = Http::post('http://example.com/authenticate', [ 'Username' => 'ADMIN', 'Password' => 'ADMIN', 'Token' => 'FK98DL-...', ]); $token = json_decode($response, true); $response3 = Http::withHeaders(['Authorization' => $token,'Content-Type' => 'application/x-www-form-urlencoded'])->get('http://example.com/api/Order/GetOrder/', [ 'DocNo' => $DocNo, ])->json(); return $response3; }
该接口通过Postman测试可正常返回结果,但Laravel中调用失败。相关路由及视图跳转代码如下:
api.php路由定义:
Route::get('show/{id}', 'show')->name('show');
视图中的跳转锚点:
<a href="{{ route('orders.show', $item['DocNo'])}}">EDIT</a></td>
问题排查及修复方案
1. 路由名称不匹配
视图中使用的路由名称是orders.show,但路由定义里的名称是show,这会导致生成的URL错误,传递的DocNo可能为空或无效。
- 修复:修改路由定义,统一路由名称:
Route::get('show/{id}', 'show')->name('orders.show');
2. Token处理错误
json_decode($response, true)返回的是数组,但Authorization请求头通常需要字符串格式(比如带Bearer前缀的token)。index方法中可能碰巧兼容,但show方法里直接把数组作为Header值会导致API无法识别,进而引发空引用错误。
- 修复:先解析出正确的token字符串,再组装Header:
$tokenData = json_decode($response, true); // 根据认证接口实际返回的结构调整key,比如返回的是['access_token' => 'xxx']就用对应key $token = $tokenData['Token']; // 如果API要求Bearer前缀,就加上,否则直接传$token $headers = [ 'Authorization' => "Bearer {$token}", 'Content-Type' => 'application/json' // 和Postman保持一致 ];
3. GET请求参数传递方式错误
Laravel的Http::get第二个参数是查询参数(会拼接成?DocNo=xxx),但如果Postman中是把DocNo作为URL路径参数(比如http://example.com/api/Order/GetOrder/123),当前写法会导致参数传递错误,API无法获取到有效参数从而返回空引用。
- 修复:如果是路径参数,直接拼接URL:
$response3 = Http::withHeaders($headers) ->get("http://example.com/api/Order/GetOrder/{$DocNo}");
4. 链式调用->json()的风险
如果请求本身失败(比如401未授权、404资源不存在),$response3可能是错误对象,直接调用->json()会触发空引用错误。
- 修复:先检查请求状态,再处理响应:
$response3 = Http::withHeaders($headers)->get('http://example.com/api/Order/GetOrder/', [ 'DocNo' => $DocNo, ]); // 调试用:打印响应内容,排查API返回的具体错误 if ($response3->failed()) { dd($response3->body()); } $data = $response3->json(); return $data;
5. Content-Type头不一致
index方法用的是application/json,show方法用的是application/x-www-form-urlencoded,和Postman中的请求头不一致可能导致API解析失败。
- 修复:查看Postman中的请求头,统一使用相同的
Content-Type。
内容的提问来源于stack exchange,提问作者Sam

