Проблема в вашем коде заключается в том, что вы не объединяете проверку reCAPTCHA с процессом отправки письма. Вот исправленный вариант:
<?php
// Файлы phpmailer
require 'phpmailer/PHPMailer.php';
require 'phpmailer/SMTP.php';
require 'phpmailer/Exception.php';
// Инициализация массива данных для ответа
$data = [];
# проверка, что ошибки нет
if (!error_get_last()) {
// Проверка reCAPTCHA
if(isset($_POST['token'])){
$secretKey = '***'; // Ваш секретный ключ reCAPTCHA
$token = $_POST['token'];
$url = 'https://www.google.com/recaptcha/api/siteverify';
// Используем cURL вместо file_get_contents для лучшей обработки ошибок
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'secret' => $secretKey,
'response' => $token,
'remoteip' => $_SERVER['REMOTE_ADDR']
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$responseKeys = json_decode($response, true);
// Если reCAPTCHA не пройдена, возвращаем ошибку
if(!$responseKeys["success"] || $responseKeys["score"] < 0.5) {
header('Content-Type: application/json');
echo json_encode([
'result' => 'error',
'info' => 'Ошибка проверки reCAPTCHA',
'desc' => 'Возможная попытка спама'
]);
exit;
}
} else {
header('Content-Type: application/json');
echo json_encode([
'result' => 'error',
'info' => 'Отсутствует токен reCAPTCHA'
]);
exit;
}
// Переменные, которые отправляет пользователь
$name = $_POST['name'] ?? '';
$tel = $_POST['tel'] ?? '';
$email = $_POST['email'] ?? '';
$number = $_POST['number'] ?? '';
$text = $_POST['text'] ?? '';
// Формирование самого письма
$title = "Заявка с сайта";
$body = "
<h2>Заявка с сайта</h2>
<b>Имя:</b> $name<br>
<b>Телефон:</b> $tel<br>
<b>Почта:</b> $email<br>
<b>Количество изделий:</b> $number<br>
<b>Сообщение:</b><br>$text
";
// Настройки PHPMailer
$mail = new PHPMailer\PHPMailer\PHPMailer();
try {
$mail->isSMTP();
$mail->CharSet = "UTF-8";
$mail->SMTPAuth = true;
//$mail->SMTPDebug = 2;
$mail->Debugoutput = function($str, $level) use (&$data) {
$data['debug'][] = $str;
};
// Настройки вашей почты
$mail->Host = 'smtp.yandex.com'; // SMTP сервера вашей почты
$mail->Username = '***'; // Логин на почте
$mail->Password = '***'; // Пароль на почте
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->setFrom('***', 'Заявка с сайта'); // Адрес самой почты и имя отправителя
// Получатель письма
$mail->addAddress('***');
// Прикрипление файлов к письму
if (!empty($_FILES['file']['name'][0])) {
for ($i = 0; $i < count($_FILES['file']['tmp_name']); $i++) {
if ($_FILES['file']['error'][$i] === 0) {
$mail->addAttachment($_FILES['file']['tmp_name'][$i], $_FILES['file']['name'][$i]);
}
}
}
// Отправка сообщения
$mail->isHTML(true);
$mail->Subject = $title;
$mail->Body = $body;
// Проверяем отправленность сообщения
if ($mail->send()) {
$data['result'] = "success";
$data['info'] = "Сообщение успешно отправлено!";
} else {
$data['result'] = "error";
$data['info'] = "Сообщение не было отправлено. Ошибка при отправке письма";
$data['desc'] = "Причина ошибки: {$mail->ErrorInfo}";
}
} catch (Exception $e) {
$data['result'] = "error";
$data['info'] = "Ошибка при отправке письма";
$data['desc'] = $e->getMessage();
}
} else {
$data['result'] = "error";
$data['info'] = "В коде присутствует ошибка";
$data['desc'] = error_get_last();
}
// Отправка результата
header('Content-Type: application/json');
echo json_encode($data);
?>
Основные изменения:
Правильная обработка reCAPTCHA:
Использовал cURL вместо file_get_contents для лучшей обработки ошибок
Добавил проверку до обработки формы
При ошибке reCAPTCHA скрипт завершается с ошибкой
Улучшенная обработка ошибок:
Добавил try-catch для обработки исключений PHPMailer
Исправил обработку файлов (используйте $_FILES вместо $file)
JSON ответ:
Теперь скрипт возвращает один JSON ответ, а не несколько
Все сообщения об ошибках стандартизированы
Безопасность:
Добавил проверку наличия токена reCAPTCHA
Использовал оператор объединения ?? для переменных формы
На стороне клиента (HTML/JS):
Убедитесь, что вы правильно реализовали reCAPTCHA v3 на клиентской стороне. Вот пример:
<script src="https://www.google.com/recaptcha/api.js?render=ВАШ_КЛЮЧ_САЙТА"></script>
<script>
document.querySelector('form').addEventListener('submit', function(e) {
e.preventDefault();
grecaptcha.ready(function() {
grecaptcha.execute('ВАШ_КЛЮЧ_САЙТА', {action: 'submit'}).then(function(token) {
// Добавляем token к данным формы
let formData = new FormData(document.querySelector('form'));
formData.append('token', token);
// Отправка формы
fetch('ваш_обработчик.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if(data.result === 'success') {
alert('Сообщение отправлено!');
} else {
alert('Ошибка: ' + data.info);
}
})
.catch(error => console.error('Error:', error));
});
});
});
</script>
Замените ВАШ_КЛЮЧ_САЙТА на ваш ключ reCAPTCHA (site key) и ваш_обработчик.php на путь к вашему PHP-скрипту.