🎅Разработка игры «Тайный Санта» на PHP
Создание веб-приложения для жеребьёвки «Тайного Санты» — отличный способ практиковаться в PHP, работе с формами и отправке электронной почты. Мы рассмотрим базовую логику: сбор участников, случайное сопоставление (пары «даритель» → «получатель») и отправку результатов по почте.
🛠️ Необходимые инструменты
- PHP (версия 7.4 или выше).
- Веб-сервер (например, Apache или Nginx) с поддержкой PHP, или локальное окружение (например, XAMPP, MAMP).
- Возможность отправки электронной почты с вашего сервера (или использование сервиса, такого как SendGrid или библиотеки PHPMailer).
Шаг 1: Сбор данных об участниках
Для начала нам нужна форма, где организатор введет имена и email-адреса участников.
index.html (или index.php для формы):
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Тайный Санта - Регистрация</title>
</head>
<body>
<h1><span class="emoji">🎁</span> Организация Тайного Санты</h1>
<form action="process.php" method="POST">
<p>Введите участников (один участник в строке: Имя,Email)</p>
<textarea name="participants" rows="10" cols="50" required>
Иван,ivan@example.com
Мария,maria@example.com
Петр,petr@example.com
...
</textarea>
<br>
<button type="submit">Провести Жеребьевку!</button>
</form>
</body>
</html>
Шаг 2: Обработка данных и жеребьёвка (PHP)
Основная логика будет находиться в файле process.php.
process.php
<?php
// 1. Получение и очистка данных
$participants_input = $_POST['participants'] ?? '';
// Разбиваем ввод на строки и удаляем пустые
$lines = array_filter(explode("\n", $participants_input));
$participants = [];
foreach ($lines as $line) {
// Разбиваем строку на Имя и Email
$parts = array_map('trim', explode(',', $line));
if (count($parts) === 2) {
// Убедимся, что Email действителен
if (filter_var($parts[1], FILTER_VALIDATE_EMAIL)) {
$participants[] = [
'name' => $parts[0],
'email' => $parts[1]
];
}
}
}
$num_participants = count($participants);
// Минимальное количество участников для игры "Тайный Санта"
if ($num_participants < 3) {
die("⛔ Нужно минимум 3 участника для жеребьевки!");
}
// 2. Логика жеребьёвки
/*
Ключевая задача: создать массив пар (даритель => получатель),
где никто не дарит подарок самому себе.
*/
$givers = $participants;
$receivers = $participants;
$matches = [];
$max_attempts = 10; // Ограничение на попытки
for ($attempt = 0; $attempt < $max_attempts; $attempt++) {
$matches = [];
$shuffled_receivers = $receivers;
shuffle($shuffled_receivers);
$success = true;
for ($i = 0; $i < $num_participants; $i++) {
$giver = $givers[$i];
$receiver = $shuffled_receivers[$i];
// Условие "Никто не дарит себе"
if ($giver['email'] === $receiver['email']) {
$success = false; // Сопоставление не удалось
break;
}
// Если все хорошо, сохраняем пару
$matches[$giver['email']] = $receiver['name'];
}
// Если все пары успешно созданы, выходим из цикла
if ($success) {
break;
}
}
if (!$success) {
die("❌ Не удалось найти подходящие пары после $max_attempts попыток. Попробуйте снова.");
}
// 3. Отправка результатов по Email
$success_count = 0;
foreach ($givers as $giver) {
$giver_email = $giver['email'];
$giver_name = $giver['name'];
$receiver_name = $matches[$giver_email];
$subject = "🌟 Вы - Тайный Санта!";
// Тело письма в HTML
$message = "
<html>
<head>
<title>Ваш подопечный</title>
</head>
<body>
<h2>Привет, $giver_name!</h2>
<p>Поздравляем! В игре 'Тайный Санта' вы дарите подарок:</p>
<h3>{$receiver_name}</h3>
<p>Не забудьте сохранить это в тайне! Счастливых праздников!</p>
</body>
</html>";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= 'From: <secretsanta@yourdomain.com>' . "\r\n";
if (mail($giver_email, $subject, $message, $headers)) {
$success_count++;
} else {
// Здесь можно добавить логирование ошибки отправки
echo "Ошибка отправки на $giver_email<br>";
}
}
echo "✅ Жеребьевка завершена! Письма отправлены $success_count участникам.";
?>
💡 Объяснение ключевой логики (Жеребьёвка)
- Инициализация: Создаются два одинаковых списка: Дарители (
$givers) и Получатели ($receivers). - Перемешивание: Список получателей (
$shuffled_receivers) случайно перемешивается (shuffle()). - Сопоставление: Каждый даритель из списка
$giversсопоставляется с получателем, находящимся на той же позиции в перемешанном списке. - Проверка условия: Проверяется, не совпадает ли даритель со своим назначенным получателем. Если совпадает, попытка считается неудачной, и весь процесс перемешивания и сопоставления повторяется, пока не будет найдено корректное решение.
🔒 Улучшения и Безопасность
- Использование PHPMailer
- Для надежной отправки почты (особенно через внешние SMTP-серверы) настоятельно рекомендуется использовать библиотеку PHPMailer вместо встроенной функции
mail(). - Валидация данных
- Добавьте более строгую валидацию входных данных, чтобы предотвратить XSS-атаки. Используйте
htmlspecialchars()при выводе данных в HTML. - Исключения
- Вы можете усложнить логику, добавив возможность указать, кого нельзя тянуть (например, «Иван не может дарить Марии»).
mail(), используемая в примере, требует правильной настройки почтового сервера (MTA) на вашем хостинге. Если письма не приходят, это, скорее всего, проблема настройки сервера, а не PHP-кода.
Комментарии (0)
Оставить комментарий