部分虛擬主機禁用了 fsockopen 等 socket 函數,導致官方 recaptchalib.php 無法正常驗證。本文提供將驗證請求改為 cURL 方式的完整修改方案。
_recaptcha_http_post 為 cURL 版本function _recaptcha_http_post($host, $path, $data, $port = 80) {
$req = _recaptcha_qsencode($data);
$url = $host . $path;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
recaptcha_check_answer 解析邏輯function recaptcha_check_answer($privkey, $remoteip, $challenge, $response, $extra_params = []) {
// ... 參數校驗略 ...
$response = _recaptcha_http_post(
RECAPTCHA_VERIFY_SERVER,
"/recaptcha/api/verify",
array_merge([
'privatekey' => $privkey,
'remoteip' => $remoteip,
'challenge' => $challenge,
'response' => $response
], $extra_params)
);
$answers = explode("\n", $response);
$recaptcha_response = new ReCaptchaResponse();
// 官方返回首行 "true" 或 "false"
if (trim($answers[0]) === 'true') {
$recaptcha_response->is_valid = true;
} else {
$recaptcha_response->is_valid = false;
$recaptcha_response->error = $answers[1] ?? 'unknown';
}
return $recaptcha_response;
}
<form action="" method="post">
<?php
require_once('recaptchalib.php');
$publickey = "你的公鑰";
$privatekey = "你的私鑰";
$resp = null;
$error = null;
if ($_POST["recaptcha_response_field"]) {
$resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
if ($resp->is_valid) {
echo "驗證通過!";
} else {
$error = $resp->error;
echo "錯誤:$error";
}
}
echo recaptcha_get_html($publickey, $error);
?>
<br/>
<input type="submit" value="提交" />
</form>
CURLOPT_RETURNTRANSFER 直接獲取響應體,避免直接輸出。true/false 判斷,更符合官方 API 文檔。