本地Livezilla聊天机器人对接REST API报错:Trying to get property of non-object
解决Livezilla USER API对接时的"Trying to get property 'answer' of non-object"错误
从你提供的错误日志、代码和API返回格式来看,问题的核心是对API返回的JSON结构解析错误,同时缺少必要的错误处理逻辑。下面是具体的问题分析和修复方案:
问题根源
- API返回结构不匹配:你的API返回的是一个数组格式(外层用
[]包裹),内容是[{"response":{"answer":"..."},200],但你的代码直接将解析后的结果当作对象去访问$sdata->answer——这显然不对,因为json_decode()解析数组后得到的是PHP数组,而且answer嵌套在数组第一个元素的response对象里。 - 缺少错误处理:如果
file_get_contents()请求API失败(比如服务未启动、网络问题),$sdata会是null,此时访问$sdata->answer也会触发同样的错误。
修复后的代码
<?php // 校验POST请求参数是否存在 if (!isset($_POST["livezilla_user_api_request"])) { http_response_code(400); echo json_encode(["error" => "Missing required request parameter"]); exit; } $requestobj = json_decode($_POST["livezilla_user_api_request"]); // 校验请求对象是否有效 if (!$requestobj || !property_exists($requestobj, 'Value') || !property_exists($requestobj, 'VisitorId')) { http_response_code(400); echo json_encode(["error" => "Invalid request data structure"]); exit; } $responseNode = [ "ResponseTo" => "", "Id" => rand(1111111, 9999999), "SearchKB" => false ]; // 构造API请求URL $url = sprintf( "http://localhost:8989/api/rest/v1.0/ask?question=%s&userid=%s", rawurlencode($requestobj->Value), $requestobj->VisitorId ); // 创建HTTP上下文,处理超时和错误响应 $context = stream_context_create([ 'http' => [ 'ignore_errors' => true, 'timeout' => 10 ] ]); // 请求API并获取响应 $sdata = file_get_contents($url, false, $context); if (!$sdata) { $responseNode["Value"] = "抱歉,暂时无法获取回复,请稍后再试。"; echo json_encode($responseNode); exit; } // 解析API响应 $apiResponse = json_decode($sdata); // 校验响应结构是否符合预期 if (!$apiResponse || !is_array($apiResponse) || !isset($apiResponse[0]->response->answer)) { $responseNode["Value"] = "抱歉,未能获取到有效回复。"; echo json_encode($responseNode); exit; } // 正确提取回复内容 $responseNode["Value"] = $apiResponse[0]->response->answer; echo json_encode($responseNode); ?>
关键修改说明
- 参数校验:添加了POST参数、请求对象结构的校验,避免因输入无效导致的错误。
- HTTP请求增强:使用
stream_context_create()设置超时和错误忽略,确保即使API返回错误状态码,也能获取响应内容用于排查。 - 响应结构修正:针对API返回的数组结构,先取第一个元素
$apiResponse[0],再访问嵌套的response->answer,正确提取回复内容。 - 友好降级:当API请求失败或响应异常时,返回友好提示,避免Livezilla触发错误日志。
调试小技巧
如果想进一步排查问题,可以临时添加日志记录,查看API返回的原始内容:
// 在file_get_contents之后添加 file_put_contents('livezilla_api_debug.log', date('Y-m-d H:i:s') . " | Response: " . $sdata . PHP_EOL, FILE_APPEND);
这样你就能在日志文件中看到API返回的真实内容,确认结构是否符合预期。
内容的提问来源于stack exchange,提问作者MC123
相关产品推荐
相关产品推荐

