/
ansukovka
/
Web
Обзор
Документация
Войти
/
ansukovka
/
Web
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
83.php
711 строк
29 KB
ansukovka
upload files
26 дек 2025, 14:41
26 дек 2025, 14:41
bd44835
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Задание 3. Форма регистрации пользователя</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; } .registration-container { width: 100%; max-width: 500px; background: white; border-radius: 20px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.2); overflow: hidden; animation: slideIn 0.6s ease; } @keyframes slideIn { from { opacity: 0; transform: translateY(-30px); } to { opacity: 1; transform: translateY(0); } } .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; position: relative; } .header h1 { font-size: 28px; margin-bottom: 10px; font-weight: 600; } .header p { opacity: 0.9; font-size: 16px; } .header:after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 60px; height: 4px; background: white; border-radius: 2px; } .form-content { padding: 40px; } .form-group { margin-bottom: 25px; position: relative; } .form-group label { display: block; margin-bottom: 8px; color: #555; font-weight: 600; font-size: 15px; } .input-container { position: relative; } .input-container i { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); color: #764ba2; font-size: 18px; } input[type="text"], input[type="password"], input[type="date"] { width: 100%; padding: 15px 15px 15px 50px; border: 2px solid #e0e0e0; border-radius: 12px; font-size: 16px; transition: all 0.3s ease; background: #fafafa; color: #333; } input:focus { border-color: #764ba2; outline: none; box-shadow: 0 0 0 3px rgba(118, 75, 162, 0.1); background: white; transform: translateY(-2px); } .input-container:hover input { border-color: #a67dc5; } .password-strength { margin-top: 8px; height: 4px; background: #e0e0e0; border-radius: 2px; overflow: hidden; position: relative; } .strength-meter { height: 100%; width: 0%; background: #ff4444; transition: width 0.3s ease; border-radius: 2px; } .requirements { margin-top: 5px; font-size: 13px; color: #888; } .requirements ul { list-style: none; padding-left: 0; } .requirements li { margin-bottom: 3px; display: flex; align-items: center; } .requirements li i { margin-right: 8px; font-size: 12px; } .requirements .valid { color: #4CAF50; } .requirements .invalid { color: #ff4444; } .buttons { display: flex; gap: 15px; margin-top: 30px; } button { flex: 1; padding: 18px; border: none; border-radius: 12px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; justify-content: center; align-items: center; gap: 10px; } button i { font-size: 18px; } .submit-btn { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3); } .submit-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4); } .reset-btn { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; box-shadow: 0 4px 15px rgba(245, 87, 108, 0.3); } .reset-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(245, 87, 108, 0.4); } .message { padding: 20px; margin-top: 25px; border-radius: 12px; border-left: 5px solid; animation: fadeIn 0.5s ease; display: none; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .success { background-color: #f0f9f0; border-color: #4CAF50; color: #2e7d32; } .error { background-color: #fff0f0; border-color: #f44336; color: #c62828; } .error ul { list-style: none; padding-left: 0; margin-top: 10px; } .error li { margin-bottom: 8px; padding-left: 25px; position: relative; } .error li:before { content: "✕"; position: absolute; left: 0; color: #f44336; } .success .success-item { margin: 10px 0; padding: 10px; background: rgba(76, 175, 80, 0.1); border-radius: 8px; display: flex; justify-content: space-between; } .success .label { font-weight: 600; color: #555; } .age-warning { font-size: 14px; color: #ff9800; margin-top: 5px; display: flex; align-items: center; gap: 8px; } .age-warning i { color: #ff9800; } .footer { text-align: center; padding: 20px; color: #888; font-size: 14px; border-top: 1px solid #eee; background: #f9f9f9; } .footer a { color: #764ba2; text-decoration: none; font-weight: 600; } .footer a:hover { text-decoration: underline; } @media (max-width: 576px) { .form-content { padding: 30px 20px; } .header { padding: 25px 20px; } .header h1 { font-size: 24px; } .buttons { flex-direction: column; } } /* Иконки Font Awesome (упрощенная версия) */ .icon { display: inline-block; width: 20px; height: 20px; background-size: contain; background-repeat: no-repeat; } .icon-user { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23764ba2'%3E%3Cpath d='M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z'/%3E%3C/svg%3E"); } .icon-lock { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23764ba2'%3E%3Cpath d='M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z'/%3E%3C/svg%3E"); } .icon-calendar { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23764ba2'%3E%3Cpath d='M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z'/%3E%3C/svg%3E"); } .icon-login { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M11 7L9.6 8.4l2.6 2.6H2v2h10.2l-2.6 2.6L11 17l5-5-5-5zm9 12h-8v2h8c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-8v2h8v14z'/%3E%3C/svg%3E"); } .icon-reset { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E"); } .icon-check { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234CAF50'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E"); } .icon-error { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f44336'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z'/%3E%3C/svg%3E"); } .icon-warning { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23FF9800'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E"); } </style> </head> <body> <div class="registration-container"> <div class="header"> <h1>Регистрация пользователя</h1> <p>Заполните форму для создания учетной записи</p> </div> <div class="form-content"> <?php $errors = []; $success = false; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $fullname = trim($_POST['fullname'] ?? ''); $login = trim($_POST['login'] ?? ''); $password = $_POST['password'] ?? ''; $birthdate = $_POST['birthdate'] ?? ''; // Валидация ФИО if (empty($fullname)) { $errors[] = "ФИО обязательно для заполнения"; } elseif (strlen($fullname) < 5) { $errors[] = "ФИО должно содержать не менее 5 символов"; } elseif (!preg_match('/^[а-яА-ЯёЁ\s\-]+$/u', $fullname)) { $errors[] = "ФИО должно содержать только русские буквы, пробелы и дефисы"; } // Валидация логина if (empty($login)) { $errors[] = "Логин обязателен для заполнения"; } elseif (strlen($login) < 3) { $errors[] = "Логин должен содержать не менее 3 символов"; } elseif (!preg_match('/^[a-zA-Z0-9_]+$/', $login)) { $errors[] = "Логин может содержать только латинские буквы, цифры и нижнее подчеркивание"; } // Валидация пароля if (empty($password)) { $errors[] = "Пароль обязателен для заполнения"; } else { if (strlen($password) < 6) { $errors[] = "Пароль должен содержать не менее 6 символов"; } if (!preg_match('/[A-Z]/', $password)) { $errors[] = "Пароль должен содержать хотя бы одну заглавную букву"; } if (!preg_match('/[0-9]/', $password)) { $errors[] = "Пароль должен содержать хотя бы одну цифру"; } } // Валидация даты рождения if (empty($birthdate)) { $errors[] = "Дата рождения обязательна для заполнения"; } else { $birthdateObj = DateTime::createFromFormat('Y-m-d', $birthdate); $today = new DateTime(); if (!$birthdateObj) { $errors[] = "Некорректный формат даты рождения"; } else { if ($birthdateObj > $today) { $errors[] = "Дата рождения не может быть в будущем"; } else { $age = $today->diff($birthdateObj)->y; if ($age < 18) { $errors[] = "Регистрация разрешена только с 18 лет. Вам " . $age . " лет"; } } } } if (empty($errors)) { $success = true; } } // Отображение ошибок if (!empty($errors)) { echo "<div class='message error' id='error-message'>"; echo "<strong><i class='icon icon-error' style='display:inline-block;width:16px;height:16px;vertical-align:text-bottom;margin-right:5px;'></i> Обнаружены ошибки:</strong>"; echo "<ul>"; foreach ($errors as $error) { echo "<li>$error</li>"; } echo "</ul>"; echo "</div>"; echo "<script>document.getElementById('error-message').style.display = 'block';</script>"; } // Отображение успешной регистрации if ($success) { $age = (new DateTime())->diff(new DateTime($_POST['birthdate']))->y; echo "<div class='message success' id='success-message'>"; echo "<strong><i class='icon icon-check' style='display:inline-block;width:16px;height:16px;vertical-align:text-bottom;margin-right:5px;'></i> Регистрация прошла успешно!</strong><br><br>"; echo "<div class='success-item'>"; echo "<span class='label'>ФИО:</span>"; echo "<span>" . htmlspecialchars($_POST['fullname']) . "</span>"; echo "</div>"; echo "<div class='success-item'>"; echo "<span class='label'>Логин:</span>"; echo "<span>" . htmlspecialchars($_POST['login']) . "</span>"; echo "</div>"; echo "<div class='success-item'>"; echo "<span class='label'>Дата рождения:</span>"; echo "<span>" . htmlspecialchars($_POST['birthdate']) . " (" . $age . " лет)</span>"; echo "</div>"; echo "</div>"; echo "<script>document.getElementById('success-message').style.display = 'block';</script>"; } ?> <form method="post" action="" id="registration-form"> <div class="form-group"> <label for="fullname">Полное имя (ФИО)</label> <div class="input-container"> <i class="icon icon-user"></i> <input type="text" id="fullname" name="fullname" value="<?= htmlspecialchars($_POST['fullname'] ?? '') ?>" placeholder="Иванов Иван Иванович" required> </div> <div class="requirements"> <ul> <li id="fullname-length" class="invalid"> <i class="icon icon-error"></i> Не менее 5 символов </li> <li id="fullname-cyrillic" class="invalid"> <i class="icon icon-error"></i> Только русские буквы </li> </ul> </div> </div> <div class="form-group"> <label for="login">Логин</label> <div class="input-container"> <i class="icon icon-login"></i> <input type="text" id="login" name="login" value="<?= htmlspecialchars($_POST['login'] ?? '') ?>" placeholder="user123" required> </div> <div class="requirements"> <ul> <li id="login-length" class="invalid"> <i class="icon icon-error"></i> Не менее 3 символов </li> <li id="login-latin" class="invalid"> <i class="icon icon-error"></i> Только латинские буквы и цифры </li> </ul> </div> </div> <div class="form-group"> <label for="password">Пароль</label> <div class="input-container"> <i class="icon icon-lock"></i> <input type="password" id="password" name="password" value="<?= htmlspecialchars($_POST['password'] ?? '') ?>" placeholder="Введите пароль" required> </div> <div class="password-strength"> <div class="strength-meter" id="strength-meter"></div> </div> <div class="requirements"> <ul> <li id="pass-length" class="invalid"> <i class="icon icon-error"></i> Не менее 6 символов </li> <li id="pass-uppercase" class="invalid"> <i class="icon icon-error"></i> Хотя бы одна заглавная буква </li> <li id="pass-number" class="invalid"> <i class="icon icon-error"></i> Хотя бы одна цифра </li> </ul> </div> </div> <div class="form-group"> <label for="birthdate">Дата рождения</label> <div class="input-container"> <i class="icon icon-calendar"></i> <input type="date" id="birthdate" name="birthdate" value="<?= htmlspecialchars($_POST['birthdate'] ?? '') ?>" required> </div> <div class="age-warning" id="age-warning"> <i class="icon icon-warning"></i> <span>Регистрация доступна только с 18 лет</span> </div> </div> <div class="buttons"> <button type="submit" class="submit-btn"> <i class="icon icon-login"></i> Зарегистрироваться </button> <button type="reset" class="reset-btn" id="reset-btn"> <i class="icon icon-reset"></i> Очистить форму </button> </div> </form> </div> <div class="footer"> <p>Все поля обязательны для заполнения</p> <p>Уже есть аккаунт? <a href="#" onclick="alert('Функция входа пока недоступна')">Войти</a></p> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const form = document.getElementById('registration-form'); const fullnameInput = document.getElementById('fullname'); const loginInput = document.getElementById('login'); const passwordInput = document.getElementById('password'); const birthdateInput = document.getElementById('birthdate'); const strengthMeter = document.getElementById('strength-meter'); // Валидация ФИО в реальном времени fullnameInput.addEventListener('input', function() { const value = this.value; const lengthValid = value.length >= 5; const cyrillicValid = /^[а-яА-ЯёЁ\s\-]+$/.test(value) || value.length === 0; updateValidation('fullname-length', lengthValid); updateValidation('fullname-cyrillic', cyrillicValid); }); // Валидация логина в реальном времени loginInput.addEventListener('input', function() { const value = this.value; const lengthValid = value.length >= 3; const latinValid = /^[a-zA-Z0-9_]*$/.test(value); updateValidation('login-length', lengthValid); updateValidation('login-latin', latinValid); }); // Валидация пароля в реальном времени passwordInput.addEventListener('input', function() { const value = this.value; const lengthValid = value.length >= 6; const uppercaseValid = /[A-Z]/.test(value); const numberValid = /[0-9]/.test(value); updateValidation('pass-length', lengthValid); updateValidation('pass-uppercase', uppercaseValid); updateValidation('pass-number', numberValid); // Обновление индикатора силы пароля let strength = 0; if (lengthValid) strength += 33; if (uppercaseValid) strength += 33; if (numberValid) strength += 34; strengthMeter.style.width = strength + '%'; strengthMeter.style.backgroundColor = strength < 33 ? '#ff4444' : strength < 66 ? '#ff9800' : '#4CAF50'; }); // Проверка возраста в реальном времени birthdateInput.addEventListener('change', function() { const birthdate = new Date(this.value); const today = new Date(); const age = today.getFullYear() - birthdate.getFullYear(); const monthDiff = today.getMonth() - birthdate.getMonth(); const actualAge = monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthdate.getDate()) ? age - 1 : age; const ageWarning = document.getElementById('age-warning'); if (actualAge < 18 && this.value) { ageWarning.innerHTML = `<i class="icon icon-warning"></i><span>Вам ${actualAge} лет. Регистрация доступна только с 18 лет</span>`; ageWarning.style.color = '#f44336'; } else if (this.value) { ageWarning.innerHTML = `<i class="icon icon-check" style="color:#4CAF50"></i><span>Вам ${actualAge} лет. Возраст соответствует требованиям</span>`; ageWarning.style.color = '#4CAF50'; } }); // Кнопка сброса формы document.getElementById('reset-btn').addEventListener('click', function() { // Сброс индикаторов валидации ['fullname-length', 'fullname-cyrillic', 'login-length', 'login-latin', 'pass-length', 'pass-uppercase', 'pass-number'].forEach(id => { const el = document.getElementById(id); el.className = 'invalid'; el.querySelector('i').className = 'icon icon-error'; }); // Сброс индикатора силы пароля strengthMeter.style.width = '0%'; // Сброс предупреждения о возрасте const ageWarning = document.getElementById('age-warning'); ageWarning.innerHTML = `<i class="icon icon-warning"></i><span>Регистрация доступна только с 18 лет</span>`; ageWarning.style.color = '#ff9800'; // Скрытие сообщений const messages = document.querySelectorAll('.message'); messages.forEach(msg => msg.style.display = 'none'); }); // Функция обновления индикатора валидации function updateValidation(elementId, isValid) { const element = document.getElementById(elementId); const icon = element.querySelector('i'); if (isValid) { element.className = 'valid'; icon.className = 'icon icon-check'; } else { element.className = 'invalid'; icon.className = 'icon icon-error'; } } // Установка максимальной датой - сегодня const today = new Date().toISOString().split('T')[0]; birthdateInput.max = today; // Инициализация валидации при загрузке if (fullnameInput.value) fullnameInput.dispatchEvent(new Event('input')); if (loginInput.value) loginInput.dispatchEvent(new Event('input')); if (passwordInput.value) passwordInput.dispatchEvent(new Event('input')); if (birthdateInput.value) birthdateInput.dispatchEvent(new Event('change')); }); </script> </body> </html>