PHP登录表单集成reCAPTCHA v3报错:Undefined property: stdClass::$score
reCAPTCHA v3 集成错误:Undefined property: stdClass::$score 分析与解决
错误原因
这个错误的核心是你直接访问了$captcha->score,但该对象并不存在score属性,常见触发场景:
- 请求方式错误:你用GET请求发送验证,但Google reCAPTCHA v3的验证接口要求使用POST请求,GET请求可能被拒绝,返回的响应中没有
score字段。 - 验证请求失败:当密钥无效、前端传递的
recaptcha_response无效/过期时,Google返回的响应仅包含success(值为false)和error-codes字段,没有score。 - 请求或解析失败:
file_get_contents可能因网络问题、服务器配置(比如禁用了该函数)返回false,此时json_decode得到的是null,访问->score必然报错。 - 未先校验验证成功状态:只有当
success为true时,响应里才会包含score字段,你跳过了这一步直接访问score,自然会在验证失败时出错。
解决方法
1. 改用POST请求发送验证
按照Google官方要求,使用POST方式提交参数,避免GET请求的限制和潜在问题。
2. 增加完整的错误处理逻辑
检查请求是否成功、JSON解析是否正常,同时先判断success状态再访问score。
3. 完善异常场景的返回逻辑
修改后的代码如下:
protected function signinCaptcha(): bool { if (!$this->saveForm()) { return false; } $response = $this->signin['recaptcha_response'] ?? ''; $secretKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'; $recaptcha_url = 'https://www.google.com/recaptcha/api/siteverify'; // 组装POST参数 $postData = http_build_query([ 'secret' => $secretKey, 'response' => $response ]); // 初始化cURL请求(比file_get_contents更稳定,支持POST) $ch = curl_init($recaptcha_url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $captchaResponse = curl_exec($ch); $curlError = curl_error($ch); curl_close($ch); // 检查cURL请求是否失败 if ($curlError || !$captchaResponse) { return false; } // 解析JSON响应 $captcha = json_decode($captchaResponse); // 检查JSON解析是否成功,且验证成功 if (!$captcha || !$captcha->success) { // 可根据需要记录error-codes排查问题 // $errorCodes = $captcha->{'error-codes'} ?? []; return false; } // 验证成功后再判断分数 return $captcha->score >= 0.5; }
额外说明
- 优先使用cURL而非
file_get_contents,因为cURL更稳定,支持更多配置(比如超时、POST请求),且在很多服务器环境中file_get_contents可能被禁用。 - 可以记录
error-codes字段的值,方便排查验证失败的具体原因(比如invalid-input-secret表示密钥无效,invalid-input-response表示前端传递的响应值无效)。
内容的提问来源于stack exchange,提问作者Matteoparma
相关产品推荐
相关产品推荐

