Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПР / Хакова Ю. М. Отчет ПР4.docx
Скачиваний:
1
Добавлен:
07.06.2026
Размер:
2.79 Mб
Скачать

Register.Php – модуль регистрации. Файл реализует обработку данных, вводимых пользователем при регистрации.

Форма содержит поля: ФИО, e-mail, логин и пароль.

После заполнения и отправки формы скрипт проверяет корректность введённых данных, уникальность логина и адреса электронной почты, а затем записывает новую запись в таблицу users.

Пароль сохраняется в зашифрованном виде с использованием функции password_hash().

При успешной регистрации пользователю выводится сообщение об успешном создании аккаунта.

Login.Php – модуль авторизации. Модуль обеспечивает вход зарегистрированных пользователей в систему.

После ввода логина и пароля производится запрос в таблицу users. Если пользователь найден и пароль совпадает (проверяется функцией password_verify()), создаётся сессия PHP, и пользователю предоставляется доступ к странице профиля. В случае ошибки выводится уведомление «Неверный логин или пароль».

Функция session_start() используется для сохранения данных авторизованного пользователя на протяжении всей работы с системой.

Profile.Php – страница профиля. Файл profile.Php отображает персональную страницу пользователя после успешного входа.

На странице выводится приветственное сообщение, имя пользователя и пример визуального блока «Прогресс изучения».

Также предоставляется возможность выхода из системы.

Если пользователь пытается открыть страницу профиля без авторизации, система автоматически перенаправляет его на страницу входа (login.php).

Logout.Php – модуль выхода из системы. Файл отвечает за завершение пользовательской сессии.

Нажатие на кнопку «Выйти» полностью удаляет данные о сессии и возвращает пользователя на страницу авторизации.

ui.php – общий интерфейсный шаблон или же вспомогательный файл, содержащий функции ui_header() и ui_footer(), которые формируют единое оформление шапки и подвала сайта. В нём подключаются стили и формируется навигация (кнопки «Вход», «Регистрация»).

Style.Css – таблица стилей. Файл assets/style.Css содержит описания внешнего вида всех элементов интерфейса: карточек, кнопок, форм и полей ввода.

Рисунок 2 – Страница регистрации

Рисунок 3 – Ошибка при попытке повторной регистрации

Рисунок 4 – Сообщение об успешной регистрации

Рисунок 5 – Страница авторизации

Рисунок 6 – Ошибка при попытке авторизации

Рисунок 7 – Страница профиля

Листинг register.php

<?php

session_start();

error_reporting(E_ALL); ini_set('display_errors', 1);

$dsn = 'pgsql:host=127.0.0.1;port=5432;dbname=interslavic_db';

$user = 'webapp';

$pass = 'PASSWORD';

try {

$pdo = new PDO($dsn, $user, $pass, [

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,

]);

} catch (PDOException $e) {

echo '<!doctype html><meta charset="utf-8"><link rel="stylesheet" href="assets/style.css">';

echo '<body class="auth-page"><div class="auth-card alert err">'

. 'Не удалось подключиться: ' . htmlspecialchars($e->getMessage()) . '</div></body>';

exit;

}

$msg=''; $ok=false;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

$fullname = trim($_POST['fullname'] ?? '');

$email = trim($_POST['email'] ?? '');

$login = trim($_POST['login'] ?? '');

$password = $_POST['password'] ?? '';

if ($fullname==='' || $email==='' || $login==='' || $password==='') {

$msg='Заполните все поля.';

} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

$msg='Некорректный e-mail.';

} else {

$chk=$pdo->prepare('SELECT 1 FROM public.users WHERE email=:e OR login=:l');

$chk->execute([':e'=>$email, ':l'=>$login]);

if ($chk->fetch()) {

$msg='Пользователь с таким e-mail или логином уже существует.';

} else {

try{

$pdo->prepare('INSERT INTO public.users (fullname,email,login,password) VALUES (:f,:e,:l,:p)')

->execute([':f'=>$fullname, ':e'=>$email, ':l'=>$login, ':p'=>password_hash($password, PASSWORD_DEFAULT)]);

$ok=true; $msg='Регистрация прошла успешно! Теперь можно войти.';

}catch(PDOException $ex){

$msg = ($ex->getCode()==='23505') ? 'Такой e-mail или логин уже зарегистрирован.'

: 'Ошибка БД: '.htmlspecialchars($ex->getMessage(), ENT_QUOTES, 'UTF-8');

}

}

}

}

?>

<!doctype html>

<html lang="ru">

<head>

<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">

<title>Регистрация — Interslavic</title>

<link rel="stylesheet" href="assets/style.css">

</head>

<body class="auth-page">

<div class="auth-card">

<div class="auth-brand">

<div class="auth-logo">IS</div>

<strong>Interslavic</strong>

</div>

<h2 class="auth-title">Создание аккаунта</h2>

<?php if ($msg): ?>

<div class="alert <?= $ok ? 'ok' : 'err' ?>" style="margin-bottom:10px;">

<?= htmlspecialchars($msg, ENT_QUOTES, 'UTF-8') ?>

</div>

<?php endif; ?>

<form class="auth-form" method="post" autocomplete="off">

<div class="auth-input">

<label>ФИО</label>

<input name="fullname" required value="<?= htmlspecialchars($_POST['fullname'] ?? '', ENT_QUOTES, 'UTF-8') ?>">

</div>

<div class="auth-input">

<label>Email</label>

<input name="email" type="email" required value="<?= htmlspecialchars($_POST['email'] ?? '', ENT_QUOTES, 'UTF-8') ?>">

</div>

<div class="auth-input">

<label>Логин</label>

<input name="login" required value="<?= htmlspecialchars($_POST['login'] ?? '', ENT_QUOTES, 'UTF-8') ?>">

</div>

<div class="auth-input">

<label>Пароль</label>

<input name="password" type="password" required>

</div>

<div class="auth-actions">

<button class="btn" type="submit">Зарегистрироваться</button>

<button class="btn secondary" type="button" onclick="location.href='login.php'">У меня есть аккаунт</button>

</div>

</form>

</div>

</body>

</html>

Листинг login.php

<?php

session_start();

require __DIR__ . '/partials/ui.php';

error_reporting(E_ALL); ini_set('display_errors', 1);

$dsn = 'pgsql:host=127.0.0.1;port=5432;dbname=interslavic_db';

$user = 'webapp';

$pass = 'PASSWORD';

try {

$pdo = new PDO($dsn, $user, $pass, [

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,

]);

} catch (PDOException $e) {

ui_header('Вход');

echo '<div class="container"><div class="card alert err">Не удалось подключиться: '

. htmlspecialchars($e->getMessage()) . '</div></div>';

ui_footer(); exit;

}

$message = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

$login = trim($_POST['login'] ?? '');

$password = $_POST['password'] ?? '';

if ($login === '' || $password === '') {

$message = 'Введите логин и пароль.';

} else {

$st = $pdo->prepare('SELECT user_id, fullname, password FROM public.users WHERE login = :l');

$st->execute([':l' => $login]);

$u = $st->fetch();

if ($u && password_verify($password, $u['password'])) {

session_regenerate_id(true);

$_SESSION['user_id'] = $u['user_id'];

$_SESSION['fullname'] = $u['fullname'];

$pdo->prepare('UPDATE public.users SET last_login = now() WHERE user_id = :id')

->execute([':id' => $u['user_id']]);

header('Location: profile.php'); exit;

} else {

$message = 'Неверный логин или пароль.';

}

}

}

?>

<!doctype html>

<html lang="ru">

<head>

<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">

<title>Вход — Interslavic</title>

<link rel="stylesheet" href="assets/style.css">

</head>

<body class="auth-page">

<div class="auth-card">

<div class="auth-brand">

<div class="auth-logo">IS</div>

<strong>Interslavic</strong>

</div>

<h2 class="auth-title">Вход в систему</h2>

<?php if ($message): ?>

<div class="alert err" style="margin-bottom:10px;">

<?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?>

</div>

<?php endif; ?>

<form class="auth-form" method="post" autocomplete="off">

<div class="auth-input">

<label>Логин</label>

<input name="login" required>

</div>

<div class="auth-input">

<label>Пароль</label>

<input name="password" type="password" required>

</div>

<div class="auth-actions">

<button class="btn" type="submit">Войти</button>

<button class="btn secondary" type="button" onclick="location.href='register.php'">Создать аккаунт</button>

</div>

</form>

<div class="auth-note">

Забыли пароль? <span class="link">пока не реализовано</span>

</div>

</div>

</body>

</html>

Листинг profile.php

<?php

session_start(); require __DIR__.'/partials/ui.php';

if(!isset($_SESSION['user_id'])){ header('Location: login.php'); exit; }

ui_header('Профиль');

?>

<div class="card">

<div style="display:flex; gap:18px; align-items:center;">

<div class="logo" style="width:64px;height:64px; font-size:22px;">

<?= strtoupper(substr($_SESSION['fullname'],0,1)).strtoupper(substr(strstr($_SESSION['fullname'],' '),1,1)) ?>

</div>

<div>

<h2 style="margin:0"><?= htmlspecialchars($_SESSION['fullname']) ?></h2>

<div style="color:#7a7a7a">Статус: обучающийся</div>

</div>

<div style="margin-left:auto">

<a class="btn secondary" href="logout.php">Выйти</a>

</div>

</div>

</div>

<div class="hero">

<div class="card progress">

<h3>Прогресс</h3>

<div class="pill"><span>Местоимения</span><b>2%</b></div>

<div class="pill"><span>Прилагательные</span><b>54%</b></div>

<div class="pill"><span>Существительные</span><b>100%</b></div>

</div>

<div class="card">

<h3>Продолжить обучение</h3>

<div style="display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; margin-top:12px">

<a class="pill" style="text-decoration:none;color:inherit" href="#"><span>Учебные материалы</span><b>▶</b></a>

<a class="pill" style="text-decoration:none;color:inherit" href="#"><span>Тестирование</span><b>▶</b></a>

<a class="pill" style="text-decoration:none;color:inherit" href="#"><span>Практика</span><b>▶</b></a>

<a class="pill" style="text-decoration:none;color:inherit" href="#"><span>Карточки</span><b>▶</b></a>

</div>

</div>

</div>

<?php ui_footer(); ?>

Листинг logout.php

<?php

session_start();

session_unset();

session_destroy();

header("Location: login.php");

exit;

Листинг product.php

<?php

require __DIR__ . '/partials/ui.php';

require __DIR__ . '/db.php';

ui_header('Курс');

if (empty($_GET['id']) || !ctype_digit($_GET['id'])) {

echo "<div class='container'><p>Курс не найден.</p></div>";

ui_footer();

exit;

}

$id = (int)$_GET['id'];

$stmt = $pdo->prepare("SELECT id, title, short_desc, full_desc, price, cover

FROM public.products

WHERE id = :id");

$stmt->execute([':id' => $id]);

$course = $stmt->fetch();

if (!$course) {

echo "<div class='container'><p>Курс не найден.</p></div>";

ui_footer();

exit;

}

?>

<section class="product-wrap">

<div class="product-card">

<div class="product-cover">

<?php if (!empty($course['cover'])): ?>

<img src="<?= htmlspecialchars($course['cover'], ENT_QUOTES, 'UTF-8') ?>" alt="">

<?php else: ?>

<div class="course-icon">📘</div>

<?php endif; ?>

</div>

<div class="product-info">

<h2><?= htmlspecialchars($course['title'], ENT_QUOTES, 'UTF-8') ?></h2>

<?php if (!empty($course['short_desc'])): ?>

<p class="short"><?= htmlspecialchars($course['short_desc'], ENT_QUOTES, 'UTF-8') ?></p>

<?php endif; ?>

<?php if (!empty($course['full_desc'])): ?>

<p class="full"><?= htmlspecialchars($course['full_desc'], ENT_QUOTES, 'UTF-8') ?></p>

<?php endif; ?>

<p class="price">

<?php if ($course['price'] > 0): ?>

Стоимость: <strong><?= $course['price'] ?> ₽</strong>

<?php else: ?>

<strong>Бесплатно</strong>

<?php endif; ?>

</p>

<a class="btn" href="login.php">Начать обучение</a>

</div>

</div>

</section>

<?php ui_footer(); ?>

Листинг catalog.php

<?php

require __DIR__ . '/partials/ui.php';

require __DIR__ . '/db.php';

ui_header('Курсы');

$items = $pdo->query("

SELECT id, title, short_desc, price, cover

FROM public.products

ORDER BY id

")->fetchAll();

?>

<section class="courses-wrap">

<div class="courses-head">

<h2>Доступные курсы</h2>

<p>Выберите интересующий вас курс по межславянскому языку</p>

</div>

<div class="courses-grid">

<?php foreach ($items as $item): ?>

<article class="course-card">

<!-- обложка -->

<?php if (!empty($item['cover'])): ?>

<div class="course-icon">

<img src="<?= htmlspecialchars($item['cover']) ?>" alt="<?= htmlspecialchars($item['title']) ?>" style="width:48px;height:48px;border-radius:10px;">

</div>

<?php else: ?>

<div class="course-icon">📘</div>

<?php endif; ?>

<!-- контент -->

<h3><?= htmlspecialchars($item['title']) ?></h3>

<p><?= htmlspecialchars($item['short_desc']) ?></p>

<div class="course-meta">

<?php if ($item['price'] > 0): ?>

<span class="price"><?= $item['price'] ?> ₽</span>

<?php else: ?>

<span class="price free">Бесплатно</span>

<?php endif; ?>

<a class="course-link" href="product.php?id=<?= (int)$item['id'] ?>">Подробнее →</a>

</div>

</article>

<?php endforeach; ?>

</div>

</section>

<?php ui_footer(); ?>

Листинг db.php

<?php

$dsn = 'pgsql:host=127.0.0.1;port=5432;dbname=interslavic_db';

$user = 'webapp';

$pass = 'PASSWORD';

try {

$pdo = new PDO($dsn, $user, $pass, [

PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,

]);

} catch (PDOException $e) {

die('Не удалось подключиться к БД: '.$e->getMessage());

}

Листинг ui.php

<?php

function ui_header(string $title=''): void {

if (session_status() === PHP_SESSION_NONE) {

session_start();

}

?>

<!doctype html>

<html lang="ru">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title><?= htmlspecialchars($title ?: 'Interslavic', ENT_QUOTES,'UTF-8') ?></title>

<link rel="stylesheet" href="assets/style.css?v=2">

</head>

<body>

<header class="header">

<a class="brand" href="index.php">

<div class="logo">IS</div>

<span class="brand-name">Interslavic</span>

</a>

<nav class="nav">

<a href="index.php">О проекте</a>

<a href="catalog.php">Курсы</a>

<a href="forum.php">Форум</a>

<?php if (isset($_SESSION['user_id'])): ?>

<a href="profile.php" class="primary">Профиль</a>

<?php else: ?>

<a href="login.php" class="primary">Вход / Регистрация</a>

<?php endif; ?>

</nav>

</header>

<div class="container">

<?php }

function ui_footer(): void { ?>

<footer class="footer">

© <?= date('Y') ?> Interslavic — учебная платформа

</footer>

</div>

</body>

</html>

<?php }

?>