Как сделать личный кабинет php
Перейти к содержимому

Как сделать личный кабинет php

  • автор:

Личный кабинет на PHP

Под личным кабинетом понимается место, где пользователь может редактировать данные своего профиля. Давайте сделаем страницу account.php , зайдя на которую пользователь увидит форму для редактирования данных своего профиля (кроме логина и пароля, их следует обрабатывать особым образом).

Обратите внимание на то, что id пользователя мы не передаем GET параметром — мы сделаем так, чтобы каждый пользователь на странице account.php видел данные своего профиля, а не чужого.

Для этого следует при авторизации пользователя мы должны в сессию записать id этого пользователя, вот так:

Затем по заходу на страницу account.php мы будем делать SELECT запрос, который будет доставать из БД пользователя с id из сессии:

Данные пользователя мы должны показать в форме для редактирования. Пусть, к примеру, это будут имя и фамилия пользователя:

После нажатия на кнопку отправки формы мы должны будем сделать запрос на обновление юзера:

Реализуйте описанный личный кабинет.

Как сделать личный кабинет php

Так получается что мой сайт mzcoding.com 3й раз меняет домен и движок и всегда при запуске нового сайта я обновлял статью по написанию Личного кабинета на PHP! В далеком 2010 это был простой ЛК на PHP 5.0, в 2014 это был ЛК 2.0 где мы обновили версию языка и код и добавили несколько плюшек. И вот настал 3й раз в этой и следующей статье мы напишем полноценный кабинет пользователя с регистрацией, авторизацией и базовым ЛК с модерацией! Разработку мы будем вести с применением PHP7 и Bootstrap 4, а так-же с применением некоторых компонентов symfony.

Первым делом создадим каталог с наименованием lk, далее откроем терминал по адресу данной папки и введем:

composer init 

У вас должен быть глобально установлен composer, что это такое и как это сделать можно прочесть тут.

Далее composer просит ввести наименование пакета! Я назову его mzcoding/lk. Далее будут еще несколько пунктов описание, автор (можете указать их на свое усмотрение). Опция Minimum Stability Укажите dev. Далее оставляйте значения по умолчанию!

Установка пакета

В конце у вас спросят, хотите ли вы установить какие либо зависимости? Вводим no. В итоге будет создан файл composer.json со следующим содержимым:

 < "name": "mzcoding/lk", "description": "Demo lk", "type": "project", "license": "mit", "authors": [ < "name": "stanislav", "email": "mzcoding@gmail.com" >], "minimum-stability": "dev", "require": <> > 

Шаг 2 — Настройка зависимостей

Теперь установим необходимые нам в работе библиотеки, первым делом установим http компоненты от symfony. Введем в терминале:

composer require symfony/http-foundation 

После установки данного пакета, установим еще один, это будет контейнер зависимостей DI. В качестве контейнера будем использовать библиотеку от разработчиков symfony, pimple

Для установки выполним:

composer require pimple/pimple 

Давайте взглянем на наш файл composer.json. Если все верно в секции require увидим что-то подобное:

"require": < "symfony/http-foundation": "^4.2@dev", "pimple/pimple": "^3.2@dev" >

Версии библиотек могут отличаться!

Давайте сразу после секции require, добавим секцию autoload, там мы укажем где composer может искать файлы нашего приложения и автоматически их подключать, для всех этих файлов мы укажем единое пространство имен. Итоговый вариант файла composer.json должен выглядеть следующим образом:

 < "name": "mzcoding/lk", "description": "Demo lk", "type": "project", "license": "mit", "authors": [ < "name": "stanislav", "email": "mzcoding@gmail.com" >], "minimum-stability": "dev", "require": < "symfony/http-foundation": "^4.2@dev", "pimple/pimple": "^3.2@dev" >, "autoload": < "psr-4": < "App\\": "app/" >, "files": [ "helpers/helpers.php" ] > > 

Так-же давайте сразу создадим все необходимые каталоги.

app — Содержит все файлы/каталоги отвечающие за логику нашего приложения.

assets — Список js/css/img файлов.

config — Файлы конфигурации приложения.

helpers — Каталог с файлом helper.php который хранит вспомогательные функции.

Шаг 3 — Создаем структуру проекта

Все наши приготовления готовы! Теперь создадим точку входа нашего проекта, в корне проекта создадим файл index.php со следующим содержимым:

 factory(function ($c) < $session = new \App\Classes\Session(); return $session; >); //БД $container['db'] = function () use(&$config) < $host = $config['db']['host'] ?? 'localhost'; $database = $config['db']['database'] ?? 'postgres'; $user = $config['db']['user'] ?? 'postgres'; $password = $config['db']['password'] ?? ''; $port = $config['db']['port'] ?? '5432'; $dsn = "pgsql:host=$host;port=$port;dbname=$database;user=$user;password=$password"; $dbh = new PDO($dsn); if($dbh)< $log = "Connected to the $database database successfully!"; > return $dbh; >; //Инициализируем вход (new App\Router($container))->init(); >catch(\App\Exceptions\LkException $e)< echo $e->getMessage(); >catch (PDOException $e)< echo $e->getMessage(); >catch(\Exception $e) < echo $e->getMessage(); > 

Давайте разберемся, что мы делаем в данном файле.

Первым делом мы инициализируем сессию, думаю тут все понятно. Далее мы подключаем наши зависимости:

require_once __DIR__ . ‘/vendor/autoload.php';

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

Далее мы открываем конструкцию try-catch тем самым отлаживая возникшие выше в коде исключительные ситуации. Обратите внимание в данном примере мы создали свой тип исключений LkException.

В блоке try мы инициализируем (получаем) все запросы (requests), а так-же инициализируем контейнер зависимостей (DI).

Далее мы добавляем в данный контейнер, конфигурацию проекта:

$container['config'] = $config;
$container['request'] = $request; 

Экземпляр класса Session (данный класс опишем немного позже)

$container['session'] = $container->factory(function ($c) < $session = new \App\Classes\Session(); return $session; >);

Обратите внимание на конструкцию добавления. Мы используем метод factory нашего контейнера, что позволяет нам получать новый экземпляр объекта данного класса каждый раз при его обращении, что соответственно позволит нам постоянно перегружать сессию при каждом запросе.

Далее мы передаем в наш контейнер подключение к БД (с помощью PDO). В нашем случае мы присваиваем переменной контейнера, анонимную функцию, которая подключается к базе и возвращает объект PDO.

//БД $container['db'] = function () use(&$config) < $host = $config['db']['host'] ?? 'localhost'; $database = $config['db']['database'] ?? 'postgres'; $user = $config['db']['user'] ?? 'postgres'; $password = $config['db']['password'] ?? ''; $port = $config['db']['port'] ?? '5432'; $dsn = "pgsql:host=$host;port=$port;dbname=$database;user=$user;password=$password"; $dbh = new PDO($dsn); if($dbh)< $log = "Connected to the $database database successfully!"; > return $dbh; >; 

В качестве примера мы используем БД PostgreSql.

И в завершении мы передаем текущий процесс в другой метод, а именно вызываем метод:

(new App\Router($container))->init();

Тут мы вызываем метод init класса Router предварительно передав наш инициализированный контейнер в конструктор класса.

Что-ж далее нам нужно создать класс Router, который примет управление текущим процессом.

Создадим файл Router.php в каталоге app:

container = $container; $controller = $request->get('c') ?? 'Login'; $this->controller = ucfirst($controller)."Controller"; $this->action = $request->get('a') ?? 'index'; > /** * Подключаем классы динамически */ public function init() < $className = 'App\\Controllers\\' . $this->controller; if(!class_exists($className)) < abort404(); >$objController = new $className($this->container); $objController->action>(); > > 

Тут все просто, при каждом запросе мы будем передавать наименование контроллера и метода (action) которые будут вызваны. Допустим мы хотим создать новый контакт, url на форму создания нового контакта может выглядеть следующим образом:

http://localhost:8000/index.php?c=contact&a=create

Система увидев такой код, вызовет метод create() у класса ContactController.php.

Теперь давайте опилим вспомогательный класс сессий, который мы использовали выше! Этот класс просто представляет собой обертку над глобальным массивом сессий. Создадим каталог Classes и добавим туда новый файл Session.php.

 return false; > public function put($key, $value) < $_SESSION[$key] = $value; >public function get($key) < if($this->has($key)) < return $_SESSION[$key]; >return null; > public function forget($key): bool < if($this->has($key)) < unset($_SESSION[$key]); return session_destroy(); >return false; > > 

Шаг 4: Контроллеры и модели

Теперь добавим дамп таблицы для пользователей которые будут регистрироваться/авторизовываться!

DROP TABLE IF EXISTS `city`; CREATE TABLE `city` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `region_id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; # Dump of table country # ------------------------------------------------------------ DROP TABLE IF EXISTS `country`; CREATE TABLE `country` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; # Dump of table region # ------------------------------------------------------------ DROP TABLE IF EXISTS `region`; CREATE TABLE `region` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `country_id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; # Dump of table users # ------------------------------------------------------------ DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(191) DEFAULT NULL, `surname` varchar(191) DEFAULT NULL, `email` varchar(191) NOT NULL DEFAULT '', `phone` varchar(191) DEFAULT NULL, `address` varchar(191) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

Теперь давайте опишем систему аутентификации! Начнем с модели Создадим в каталоге Models базовую модель Model.php:

db = $db; > /** * Вывод любых данных * @return array */ public function getData() < $query = $this->db->query("SELECT * from table>"); return $query->fetchAll(); > public function getItem(int $id) < $query = $this->db->query("SELECT * from table> WHERE return $query->fetchObject(); > /** * Добавление любых данных * @param array $params * @return bool|object */ public function insertData(array $params) < $values = []; $out = ""; $i = 0; foreach($params as $key =>$value) < $values[] = $value; $out .= ($i) ? ",?" : "?"; $i++; >$sqlPrepare = "INSERT INTO users(".implode(",", array_keys($params)).") VALUES($out)"; $statement = $this->db->prepare($sqlPrepare); $status = $statement->execute($values); if($status) < $id = $this->db->lastInsertId(); return $this->getItem($id); > return $status; > > 

Думаю здесь все понятно из комментариев, мы просто описываем базовые методы для всех моделей!

Давайте начнем с пользователей и создадим модель Users:

id; $status = $user->status; $sql = "SELECT status FROM users WHERE $query = $this->db->query($sql); $r = $query->fetchObject(); if((bool)$r->status !== $status) < $user->status = (bool)$r->status; return true; > return false; > public function IsRefreshAdmin($user): bool < $id = (int)$user->id; $isAdmin = (bool)$user->isadmin; $sql = "SELECT isadmin FROM users WHERE $query = $this->db->query($sql); $r = $query->fetchObject(); if((bool)$r->isadmin !== $isAdmin) < return true; >return false; > /** * @return array */ public function getUsersForFalseStatus() < $sql = "SELECT * FROM users WHERE status = false"; $query = $this->db->query($sql); return $query->fetchAll(); > public function login($email, $password) < $sql = "SELECT * FROM users WHERE email = '".$email."' AND password = '".$password."'"; $query = $this->db->query($sql); $result = $query->fetchObject(); return $result ?? null; > public function status(int $id, bool $status) //: void - for php 7.1 or higher < $sql = "UPDATE users SET status=? WHERE $stmt = $this->db->prepare($sql); $stmt->execute([$status, $id]); > > 

Когда у нас описана модель мы можем приступить к логики приложения и сделать систему регистрации/авторизации пользователей!

Первым делом как и с моделями мы создадим базовый контроллер, для этого добавим каталог Controllers и добавим в него файл BaseController.php:

di = $di; >else < abort404(); >> /** * @return array */ protected function getConfig(): array < if($this->di) < return $this->di['config']; > $config = include(ROOT_PATH . '/config/config.php'); return $config; > /** * Генерация views и параметров * @param $file_name * @param array $params * @throws LkException */ protected function view($file_name, array $params = []) < $ext = ".phtml"; $path = __DIR__ . "/../Views/"; if(!file_exists($path . $file_name.$ext)) < throw new LKException( "View file not found" ); >ob_start(); if($params) < extract($params); >$template = include($path . $file_name . $ext); echo $template; ob_get_contents(); ob_end_flush(); > > 

Конструктор данного контроллера принимает все пришедшие зависимости (например данные формы и любые другие данные сервера или пользовательского ввода)

Метод getConfig() возвращает наш файл конфигурации, а метод view() отвечает за вывод файлов представления и передачу параметров в них.

Далее давайте добавим файлы контроллеров отвечающих за регистрацию и авторизацию пользователей!

Добавим еще один контроллер RegisterController.php:

di['db'])) ->getData(); $regions = (new \App\Models\Region($this->di['db'])) ->getData(); $cities = (new \App\Models\City($this->di['db'])) ->getData(); $params = [ 'countries' => $countries, 'regions' => $regions, 'cities' => $citites, 'config' => $this->getConfig() ]; return $this->view('register',$params); > /** * Обработчик регистрации */ public function register() < // dump($this->di['request']->server->get('REQUEST_METHOD')); $requestMethod = $this->di['request']->server->get('REQUEST_METHOD'); if($requestMethod != 'POST') < abort404(); >$data = $this->di['request']->request->all(); /** ТУТ МОЖЕТ БЫТЬ ВАЛИДАЦИЯ ДАННЫХ * П.С: Я ее опускаю */ if(isset($data['password_confirmation'])) < unset($data['password_confirmation']); >$data['password'] = _hpswd($data['password']); if(is_array($data)) < $db = $this->di['db']; $objUser = new User($db); if($objUser = $objUser->insertData($data)) < $this->di['session']->put('user', $objUser); return redirect($this->getConfig()['url'] .'/?c=login'); > dump('Error insert database'); > > > 

Теперь посмотрим как будет выглядеть представление, по факту это просто форма регистрации register.phtml:

        Регистрация на сайте /assets/bootstrap.min.css" rel="stylesheet"> /assets/signin.css" rel="stylesheet"> /assets/main.css" rel="stylesheet"> 

Зарегистрируйтесь пожалуйста

Уже есть аккаунт? /?c=login">Войти

Основные данные



Адрес

Пароль

Подписаться на новости:

© 2017-2018

И следом добавим контроллер авторизации LoginController.php

getConfig(); $user = $this->di['session']->get('user') ?? null; if($user) < return redirect($config['url'] .'/?c=account'); >$params = [ 'config' => $config ]; return $this->view('login', $params); > public function login() < $requestMethod = $this->di['request']->server->get('REQUEST_METHOD'); if($requestMethod != 'POST') < abort404(); >$data = $this->di['request']->request->all(); $email = $data['email']; $password = _hpswd($data['password']); $objUser = new User($this->di['db']); if($objUser = $objUser->login($email, $password)) < $this->di['session']->put('user', $objUser); return redirect($this->getConfig()['url'] .'/?c=login'); > dump('Error: login incorrect'); > > 

Форма входа будет выглядеть следующим образом login.phtml:

        Авторизация на сайте /assets/bootstrap.min.css" rel="stylesheet"> /assets/signin.css" rel="stylesheet"> 

Пожалуйста, войдите

Нет аккаунта? /?c=register">Регистрация

© 2017-2018

Далее сразу-же создадим и опишем контроллер отвечающий за вывод ЛК AccountController.php.

getConfig(); $user = $this->di['session']->get('user') ?? null; if(!$user) < return redirect($config['url'] .'/?c=login'); >//Обновляем сессионные данные $objUser = new User($this->di['db']); if($objUser->IsRefreshAdmin($user)) < $this->di['session']->forget('user'); return redirect($config['url'] .'/?c=login'); > if($objUser->IsRefreshStatus($user)) < return redirect($config['url'] .'/?c=account'); >$params = [ 'config' => $config, 'user' => $user, //треш 'country' => dbhelper('country', $this->di['db'], $user->country_id), 'region' => dbhelper('region', $this->di['db'], $user->region_id), 'city' => dbhelper('city', $this->di['db'], $user->city_id), ]; return $this->view('account', $params); > public function logout() < $config = $this->getConfig(); $this->di['session']->forget('user'); return redirect($config['url'] .'/?c=login'); > > 

И так-же посмотрим на въюху account.php:

isadmin): ?>В админку  /?c=account&a=logout">Выход status): ?> 

Ваш аккаунт на модерации

Ваш аккаунт активен


Имя Фамилия name?> surname?>
E-mail email?>
Телефон phone?>
Адрес address?>
Страна/Регион/Город name?>/name?>/name?>

Шаг 5 — Заключительный

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

 function dump($data) < echo "
"; print_r($data); echo "

"; die; > /** * Редирект * @param $url * @param bool $permanent */ if(!function_exists('redirect')) < function redirect($url, $permanent = false) < if (headers_sent() === false) < header('Location: ' . $url, true, ($permanent === true) ? 301 : 302); >exit(); > > function _hpswd($pswd) < return hash("sha256", $pswd); >function dbhelper($type, $db, int $id) < $obj = new \App\Models\Country($db); switch($type) < case 'region': $obj = new \App\Models\Region($db); break; case 'city': $obj = new \App\Models\City($db); break; >return $obj->getItem($id); >

Модели стран, регионов и городов, а так-же логику администратора вы можете описать сами или найти в репозитории проекта.

Все вопросы пишите в комментариях

Как создать авторизацию и личный кабинет на сайте?

Я начинающий вэб-разработчик. У меня не получается создать личный кабинет. Если авторизация хоть и небольшая уже есть(При переходе на другую страницу сессия пропадает), то личный кабинет у меня не получается сделать. Я обрыл пол интернета, но ничего не нашел. Я не прошу сделать все за меня. Покидайте ресурсов, где можно научится этому.

  • Вопрос задан более трёх лет назад
  • 13462 просмотра

Комментировать
Решения вопроса 0
Ответы на вопрос 3
xmoonlight @xmoonlight
https://sitecoder.blogspot.com

session_start();
в начале каждой страницы в ЛК должно присутствовать, чтобы получить доступ к чтению значений переменных сессии.

Ответ написан более трёх лет назад
Нравится 1 2 комментария
Helig @Helig Автор вопроса

Это все есть, но пропадают значения. Сессия то работает, а вот взаимодействовать с ней больше нельзя.

xmoonlight @xmoonlight
Helig, значит куки в браузере не сохраняются.

nepster-web

nepster-web @nepster-web

Посмотрите в сторону frameworks. Есть много видео курсов на youtube которые решают вашу проблему.
https://www.youtube.com/watch?v=3hSJLgRvn-E

Но лучше, читайте книги и изучайте детальнее язык программирования, чтобы иметь больше понимания. Не торопитесь делать проекты.

Ответ написан более трёх лет назад
Helig @Helig Автор вопроса

У меня просто скоро конкурс по вэб-разработке среди школьников, я уже все продумал кроме этого(((( Все готово кроме регистрации и т.д.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *