Вещь index php user registration. Простая система регистрации пользователей


На множестве сайтов, которые мы каждый день просматриваем в сети, почти на всех имеется пользовательская регистрация. В том уроке мы пробежимся по основам пользовательского управления, заканчивая простой Областью Участника, которую Вы можете осуществить на своем собственном вебсайте.

Этот урок рассчитан для начинающих изучение php где мы рассмотрим основы управления пользователями.

Шаг-1

Создадим в базе таблицу user в которой, мы будем хранить информацию о пользователях в таблице 4 поля

  • UserID
  • Username
  • Password
  • EmailAddress

Используйте SQL запрос ниже для создания базы данных

CREATE TABLE `users` ( `UserID` INT(25 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , `Username` VARCHAR(65 ) NOT NULL , `Password` VARCHAR(32 ) NOT NULL , `EmailAddress` VARCHAR(255 ) NOT NULL ) ;

session_start () ; $dbhost = "localhost" ; // Имя хоста где расположен сервер mysql обычно localhost $dbname = "database" ; // Имя базы данных $dbuser = "username" ; // Имя пользователя базы данных $dbpass = "password" ; // Пароль для доступа к базе данных mysql_connect ($dbhost , $dbuser , $dbpass ) or die ("MySQL Error: " . mysql_error () ) ; mysql_select_db ($dbname ) or die ("MySQL Error: " . mysql_error () ) ; ?>

Этот файл отвечает за подключение к базе данных и будет выводиться на всех страницах. Рассмотрим строки кода более подробно

session_start();

Эта функция начинает сессию для нового пользователя, далее в ней мы будем хранить данные о ходе сессии, чтобы мы могли узнавать пользователей которые уже прошли идентификацию

mysql_connect($dbhost, $dbuser, $dbpass) or die("MySQL Error: " . mysql_error());

mysql_select_db($dbname) or die("MySQL Error: " . mysql_error());

Каждая из этих функций выполняет отдельные, но связанные задачи.

Функция mysql_connect выполняет соединение с сервером баз данных MySQL в качестве параметров в скобках указаны переменные которым присвоены соответствующие значения Хост, Имя пользователя, Пароль если данные не верные выдаст сообщение об ошибке

Функция mysql_select_db выбирает базу данных имя которой мы присвоили переменной $dbname , в случае если не удаётся найти базу выводит сообщение об ошибке

Шаг-2 Создаем файл index.php

Немало важным элементом на нашей странице – является первая строка PHP; эта строка будет включать файл, который мы создали выше (base.php ), и по существу позволим нам обращаться к чему-нибудь от того файла в нашем текущем файле. Мы сделаем это со следующей строкой кода PHP. Создайте файл, названный index.php, и поместите этот код наверху.

Создайте новый файл index.php и вставите в самое начало следующий код

Эта строка будет подключать фаил который мы создали выше (base.php), что позволит нам обращаться к коду того файла в нашем текущем файле.

Это осуществляет функция include()

Теперь мы займёмся созданием внешнего интерфейса, где пользователь будет вводить свои данные для регистрации, а если он уже зарегистрирован дать возможность изменения данных. Так как этот урок нацелен на PHP мы не будем разбираться с кодом HTML/CSS внешний вид сделаем потом когда мы создадим нашу таблицу стилей CSS, а пока просто вставим этот код после предыдущей строки.

Система управления пользователями <title> </span> <span><link rel="stylesheet" href="/style.css" type="text/css" /> </span> </head> <body> <span><div id="main">Сюда вставим php код </div> </p> <p>Теперь прежде чем пристать php программу разберём принцип её работы, что в той или иной ситуации надо выводит на экран:</p> <ol><li>Если пользователь уже вошёл то показываем страницу с различными опциями которые были скрыты до регистрации.</li> <li>Если пользователь еще не вошёл но прошёл регистрацию то показываем форму для ввода логина и пароля.</li> <li>Если 1 и 2 пункт не выполнен выводим форму для регистрации.</li> </ol><p>Выглядеть это будет так:</p> <p><?php </span> <span>if (! empty empty </span> <span>{ </span> <span>// Здесь выводиться скрытые опции </span> <span>} </span> <span>elseif (! empty empty ($_POST [ "password" ] ) ) </span> <span>{ </span> <span>// Выводим форму для входа </span> <span>} </span> <span>else </span> <span>{ </span> <span>// Выводим форму для регистрации </span> <span>} </span> <span>?> </p> <p>Когда пользователь проходит авторизацию на нашем сайте, информация сохраняется в сессии получить к ней доступ мы можем через глобальный массив <b>$ _SESSION </b>. С помощью функции empty и знака! в условии if мы проверяем имеет ли переменная значение, если переменная имеет значение выполняем код между фигурных скобок.</p> <p>В следующей строке всё работает тем же образом, только на этот раз с помощью <b>$ _POST </b> глобального массива. Этот массив содержит какие либо данные переданные через форму входа которую мы создадим позже. Последняя условие else выполниться в том случае если предыдущие условия не удовлетворяются.</p> <p>Теперь когда мы понимаем логику давайте вставим следующий код в файл index.php между тегами <div></p> <p><?php </span> <span>if (! empty ($_SESSION [ "LoggedIn" ] ) && ! empty ($_SESSION [ "Username" ] ) ) </span> <span>{ </span> <span>?> </span> <span> <h1>Пользовательская зона</h1> </span> <span> <p Спасибо что вошли! Вы <b><?= $_SESSION [ "Username" ] ?> </b> и Ваш адрес электронной почты <b><?= $_SESSION [ "EmailAddress" ] ?> </b>.</p> </span> <span><?php </span> <span>} </span> <span>elseif (! empty ($_POST [ "username" ] ) && ! empty ($_POST [ "password" ] ) ) </span> <span>{ </span> <span>$username = mysql_real_escape_string ($_POST [ "username" ] ) ; </span> <span>$password = md5 (mysql_real_escape_string </span> <span>$checklogin = mysql_query (</span> <span>if (mysql_num_rows ($checklogin ) == 1 ) </span> <span>{ </span> <span>$row = mysql_fetch_array ($checklogin ) ; </span> <span> echo <span>"<h1>Вы успешно вошли</h1>" </span>; </span> <span> echo <span>"<p>Сейчас вы будете переадресованы в ваш профиль.</p>" </span>; </span> <span> echo <span>"<meta content="=2;index.php" />" </span>; </span> <span>} </span> <span>else </span> <span>{ </span> <span> echo "<h1>Ошибка</h1>" ; </span> <span> echo <span>"<p>Ваша учётная запись не найдена или вы неправильно ввели логин или пароль. <a href=\" index.php\" >Попробовать снова </a>.</p>" </span>; </span> <span>} </span> <span>} </span> <span>else </span> <span>{ </span> <span>?> </span> <h1>Вход</h1> <span> <p>Хорошо что зашли Регистрация .</p> </span> <span> <form method="post" action="index.php" name="loginform" id="loginform"> </span> <fieldset> <span> <label for="username">Логин:</label><input type="text" name="username" id="username" /><br /> </span> <span> <label for="password">Пароль:</label><input type="password" name="password" id="password" /><br /> </span> <span> <input type="submit" name="login" id="login" value="Войти" /> </span> </fieldset> </form> <span><?php </span> <span>} </span> <span>?> </p> <p>В этом участке кода две функции,это<b>mysql _real _escape _string </b>которая экранирует специальные символы в строках для использования в базе данных тем самым обезопасит вас от нехорошихлюдей, и <b>md 5 </b> эта функция шифрует всё что передано ей в качестве параметра, в данном случае это пароль в глобальном массиве <b>$_POST </b>. Всё результаты работы функций мы присваиваем переменным<b>$username , <span>$password </span> </b>.</p> <p>$checklogin = mysql_query (<span>"SELECT * FROM users WHERE Username = "" </span>. $username . "" AND Password = "" . $password . """ ) ; </span> <span>if (mysql_num_rows ($checklogin ) == 1 ) </span> <span>{ </span> <span>$row = mysql_fetch_array ($checklogin ) ; </span> <span>$email = $row [ "EmailAddress" ] ; </span> <span>$_SESSION [ "Username" ] = $username ; </span> <span>$_SESSION [ "EmailAddress" ] = $email ; </span> <span>$_SESSION [ "LoggedIn" ] = 1 ; </p> <p>В этом участке кода нам надо проверить существует ли такой пользователь,для этого направляем запрос в базу данных, вытащить все поля из таблицы users где поля Username и Password равны переменным<b>$username и $password </b>. Результат запроса заносим в переменную<b>$checklogin </b> далее в условии <b>if </b> функция <b>mysql _num _row </b>s считает количество строк в запросе к базе и если равно 1 то есть пользователь найденвыполняем код в фигурных скобках, функция <b>mysql _fetch _array </b>преобразовывает результат запроса из <b>$checklogin </b>в ассоциативный массив, присваиваеваем значение поля EmailAddress переменной <b>$email </b>для использовать в дальнейшем.</p> <p>Заносим логин и email в текущею сессию после этого пользователь перенаправляется в свою учётную запись.</p> <p><b>Шаг-3 </b></p> <p>Теперь надо сделать страницу где пользователи будут регистрироваться.</p> <p>Создаем файл register.phpи скопируйте в него следующий код:</p> <p><?php include "base.php" ; ?> </span> <span><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> </span> <span><html xmlns="http://www.w3.org/1999/xhtml"> </span> <span><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </span> <span><title> Система управления пользователями - Регистрацияtitle> </span> <span><link rel="stylesheet" href="/style.css" type="text/css" /> </span> </head> <body> <div id="main"> <span><?php </span> <span>if (! empty ($_POST [ "username" ] ) && ! empty ($_POST [ "password" ] ) ) </span> <span>{ </span> <span>$username = mysql_real_escape_string ($_POST [ "username" ] ) ; </span> <span>$password = md5 (mysql_real_escape_string ($_POST [ "password" ] ) ) ; </span> <span>$email = mysql_real_escape_string ($_POST [ "email" ] ) ; </span> <span>$checkusername = mysql_query (<span>"SELECT * FROM users WHERE Username = "" </span>. $username . """ ) ; </span> <span>if (mysql_num_rows ($checkusername ) == 1 ) </span> <span>{ </span> <span> echo "<h1>Ошибка</h1>" ; </span> <span> echo <span>"<p>Такой логин уже занят p>" </span>; </span> <span>} </span> <span>else </span> <span>{ </span> <span>$registerquery = mysql_query (<span>"INSERT INTO users (Username, Password, EmailAddress) VALUES("" </span>. $username . "", "" . $password . "", "" . $email . "")" ) ; </span> <span>if ($registerquery ) </span> <span>{ </span> <span> echo "<h1>Отлично</h1>" ; </span> <span> echo <span>"<p>Ваша учетная запись была успешно создана. Вы можете<a href=\" index.php\" >Воити</a>.</p>" </span>; </span> <span>} </span> <span>else </span> <span>{ </span> <span> echo "<h1>Ошибка</h1>" ; </span> <span> echo <span>"<p>Попробуйте повторить регистрацию снова.</p>" </span>; </span> <span>} </span> <span>} </span> <span>} </span> <span>else </span> <span>{ </span> <span>?> </span> <span> <h1>Регистрация</h1> </span> <span> <form method="post" action="register.php" name="registerform" id="registerform"> </span> <fieldset> <span> <label for="username">Логин:</label><input type="text" name="username" id="username" /><br /> </span> <span> <label for="password">Пароль:</label><input type="password" name="password" id="password" /><br /> </span> <span> <label for="email">Email:</label><input type="text" name="email" id="email" /><br /> </span> <span> <input type="submit" name="register" id="register" value="Регистрация" /> </span> </fieldset> </form> <span><?php </span> <span>} </span> <span>?> </span> </div> </body> </html> </p> <p>В этом коде есть немного нового, запись в базу данных</p> <p>Это такой же запрос к базе данных который был раньше только теперь мы не получаеминформацию, а записываем командой INSERT , первым деломнадо указать в какие поля будет вноситься информация а в область VALUES информация которая будет записана в нашем случае это переменные со значением которые были переданы пользователем.Обратите особое внимание правила формирования запросов.</p> <p><b>Шаг-4 Завершение </b></p> <p>Для того чтобы пользователь мог выйти создайте файл logout.php и скопируйте в него код:</p> <p><?php include "base.php; <span>$_SESSION = array(); session_destroy(); ?> </span> <meta http-equiv=" refresh" content=" 0 ; index. php" </p> <p>В результате этого кода происходит сбросглобального массива $_SESSION и разрушение сессии, не забудьтев опция пользователя поставить ссылку на этот фаил.</p> <p>И наконец придадим стиль всему вышеописанному, создайте файл style.css и поместите туда следующий ниже код.</p> <p>* { </span> <span>margin : 0 ; </span> <span>padding : 0 ; </span> <span>} </span> body <span>{ </span> <span>} </span> a <span>{ </span> <span>color : #000 ; </span> <span>} </span> a<span>:hover , a:active , a:visited { </span> <span>text-decoration : none ; </span> <span>} </span> <span>#main { </span> <span>width : 780px ; </span> <span>margin : 0 auto ; </span> <span>margin-top : 50px ; </span> <span>padding : 10px ; </span> <span>background-color : #EEE ; </span> <span>} </span> form fieldset <span>{ border : 0 ; } </span> form fieldset p br <span>{ clear : left ; } </span> label <span>{ </span> <span>margin-top : 5px ; </span> <span>display : block ; </span> <span>width : 100px ; </span> <span>padding : 0 ; </span> <span>float : left ; </span> <span>} </span> input <span>{ </span> <span>font-family : Trebuchet MS; </span> <span>border : 1px solid #CCC ; </span> <span>margin-bottom : 5px ; </span> <span>background-color : #FFF ; </span> <span>padding : 2px ; </span> <span>} </span> input<span>:hover { </span> <span>border : 1px solid #222 ; </span> <span>background-color : #EEE ; </span> <span>} </p> <p>Вот в принципе и всё конечно приведенный в этом уроке пример далёк от совершенства но он и был рассчитан для начинающих чтобы дать понятие основ.</p> <p>Разберём некоторые части данного кода</p> <p>$username = mysql_real_escape_string($_POST["username"]); </p> <p>$password = md5(mysql_real_escape_string($_POST["password"])); </p> <p>В этом участке кода две функции,этоmysql _real _escape _string которая экранирует специальные символы в строках для использования в базе данных тем самым обезопасит вас от нехорошихлюдей, и md 5 эта функция шифрует всё что передано ей в качестве параметра, в данном случае это пароль в глобальном массиве $_POST . Всё результаты работы функций мы присваиваем переменным$username , <span>$password </span>.</p> <td class="nbgu"> </td> <td class="nbtu light"> </td> <td class="nbgu"> </td> <td class="nbtu light">Trackbacks (0) </td> <td width="49.5%" class="nbgu"> </td> <p><b>Updated on: </b> 2018-03-12 </p><p><b>Posted on: </b> 2016-12-21 </p><p><i>Over time PHP has been adding features that promote the development of secure applications, as well deprecated or removed features that made it easy to write insecure code.</i></p><p>Read this tutorial to learn how to create a modern login and registration system that takes advantage of PHP security-focused features and uses jQuery to send AJAX requests and Bootstrap to provide a fast and nice user interface that can work regardless if you use other frameworks or not. </p><br clear="all"><br><p>If you have questions or comments you can post a message as comment to this article or in its .</p><h1>Change Log</h1><p>2017-03-27: Added more download and install information using the composer tool.</p><p>2017-01-01: Updated the article to reflect that these continue to be secure practices in 2017</p><br><br><br clear="all"><h2>You need to be a registered user or login to post a comment</h2> <h2>Login Immediately with your account on:</h2><table align="center"><tr><td align="right"> </td><td> </td><td align="right"> </td><td> </td> </tr><tr><td align="right"> </td><td> </td><td align="right"> </td><td> </td> </tr><tr><td align="right"> </td><td> </td><td align="right"></td></tr></table> <p>Процесс создания системы регистрации – это довольно большой объем работы. Вам нужно написать код, который бы перепроверял валидность email-адресов, высылал email-письма с подтверждением, предлагал возможность восстановить пароль, хранил бы пароли в безопасном месте, проверял формы ввода и многое другое. Даже когда вы все это сделаете, пользователи будут регистрироваться неохотно, так как даже самая минимальная регистрация требует их активности.</p><p>В сегодняшнем руководстве мы займемся разработкой простой системы регистрации, с использованием которой вам не понадобятся никакие пароли! В результаты мы получим, систему, которую можно будет без труда изменить или встроить в существующий PHP-сайт. Если вам интересно, продолжайте чтение.</p><p><b>PHP </b> </p><p>Теперь мы готовы к тому, чтобы заняться кодом PHP. Основной функционал системы регистрации предоставляется классом User, который вы можете видеть ниже. Класс использует (), представляющую собой минималистскую библиотеку для работы с базами данных. Класс User отвечает за доступ к базам данных, генерирование token-ов для логина и их валидации. Он представляет нам простой интерфейс, который можно без труда включить в систему регистрации на ваших сайтах, основанных на PHP.</p><p><b>User.class.php </b></p><p> // Private ORM instance<br> private $orm;</p><p> /**<br> * Find a user by a token string. Only valid tokens are taken into<br> * consideration. A token is valid for 10 minutes after it has been generated.<br> * @param string $token The token to search for<br> * @return User<br> */</p><p>Public static function findByToken($token){</p><p> // find it in the database and make sure the timestamp is correct</p><p> <br> ->where("token", $token)<br> ->where_raw("token_validity > NOW()")<br> ->find_one();</p><p>If(!$result){<br> return false;<br> }</p><p>Return new User($result);<br> }</p><p> /**<br> * Either login or register a user.<br> * @return User<br> */</p><p>Public static function loginOrRegister($email){</p><p> // If such a user already exists, return it</p><p>If(User::exists($email)){<br> return new User($email);<br> }</p><p> // Otherwise, create it and return it</p><p>Return User::create($email);<br> }</p><p> /**<br> * Create a new user and save it to the database<br> * @param string $email The user"s email address<br> * @return User<br> */</p><p>Private static function create($email){</p><p> // Write a new user to the database and return it</p><p> $result = ORM::for_table("reg_users")->create();<br> $result->email = $email;<br> $result->save();</p><p>Return new User($result);<br> }</p><p> /**<br> * Check whether such a user exists in the database and return a boolean.<br> * @param string $email The user"s email address<br> * @return boolean<br> */</p><p>Public static function exists($email){</p><p> // Does the user exist in the database?<br> $result = ORM::for_table("reg_users")<br> ->where("email", $email)<br> ->count();</p><p>Return $result == 1;<br> }</p><p> /**<br> * Create a new user object<br> * @param $param ORM instance, id, email or null<br> * @return User<br> */</p><p>Public function __construct($param = null){</p><p>If($param instanceof ORM){</p><p> // An ORM instance was passed<br> $this->orm = $param;<br> }<br> else if(is_string($param)){</p><p> // An email was passed<br> $this-><br> ->where("email", $param)<br> ->find_one();<br> }<br> else{</p><p>If(is_numeric($param)){<br> // A user id was passed as a parameter<br> $id = $param;<br> }<br> else if(isset($_SESSION["loginid"])){</p><p> // No user ID was passed, look into the sesion<br> $id = $_SESSION["loginid"];<br> }</p><p> $this->orm = ORM::for_table("reg_users")<br> ->where("id", $id)<br> ->find_one();<br> }</p><p> /**<br> * Generates a new SHA1 login token, writes it to the database and returns it.<br> * @return string<br> */</p><p>Public function generateToken(){<br> // generate a token for the logged in user. Save it to the database.</p><p> $token = sha1($this->email.time().rand(0, 1000000));</p><p> // Save the token to the database, <br> // and mark it as valid for the next 10 minutes only</p><p> $this->orm->set("token", $token);<br> $this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")");<br> $this->orm->save();</p><p>Return $token;<br> }</p><p> /**<br> * Login this user<br> * @return void<br> */</p><p>Public function login(){</p><p> // Mark the user as logged in<br> $_SESSION["loginid"] = $this->orm->id;</p><p> // Update the last_login db field<br> $this->orm->set_expr("last_login", "NOW()");<br> $this->orm->save();<br> }</p><p> /**<br> * Destroy the session and logout the user.<br> * @return void<br> */</p><p>Public function logout(){<br> $_SESSION = array();<br> unset($_SESSION);<br> }</p><p> /**<br> * Check whether the user is logged in.<br> * @return boolean<br> */</p><p>Public function loggedIn(){<br> return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id;<br> }</p><p> /**<br> * Check whether the user is an administrator<br> * @return boolean<br> */</p><p>Public function isAdmin(){<br> return $this->rank() == "administrator";<br> }</p><p> /**<br> * Find the type of user. It can be either admin or regular.<br> * @return string<br> */</p><p>Public function rank(){<br> if($this->orm->rank == 1){<br> return "administrator";<br> }</p><p>Return "regular";<br> }</p><p> /**<br> * Magic method for accessing the elements of the private<br> * $orm instance as properties of the user object<br> * @param string $key The accessed property"s name <br> * @return mixed<br> */</p><p>Public function __get($key){<br> if(isset($this->orm->$key)){<br> return $this->orm->$key;<br> }</p><p>Return null;<br> }<br>} <br>Token-ы генерируются при помощи алгоритма , и сохраняются в базу данных. Мы используем из MySQL для установки значения в колонку token_validity, равного 10 минутам. При валидации token, мы сообщаем движку, что нам нужен token, поле token_validity пока еще не истекло. Таким образом мы ограничиваем время, в течение которого token будет валиден.</p><p>Обратите внимание на то, что мы используем волшебный метод __get () в конце документа, чтобы получить доступ к свойствам объекта user. Это позволяет нам осуществить доступ к данным, которые хранятся в базе данных в виде свойств: $user->email, $user->token. Для примера давайте посмотрим, как мы можем использовать этот класс в следующем фрагменте кода:</p><p><img src='https://i2.wp.com/coolwebmasters.com/uploads/posts/2013-08/thumbs/1377077855_simple-registration-system-05.jpg' width="100%" loading=lazy></p><br>Еще один файл, в котором хранится необходимый функционал, это functions.php. Там у нас есть несколько вспомогательных функций, которые позволяют нам сохранить остальной код более опрятным.<p><b>Functions.php </b></p><p>Function send_email($from, $to, $subject, $message){</p><p> // Helper function for sending email</p><p> $headers = "MIME-Version: 1.0" . "\r\n";<br> $headers .= "Content-type: text/plain; charset=utf-8" . "\r\n";<br> $headers .= "From: ".$from . "\r\n";</p><p>Return mail($to, $subject, $message, $headers);<br>}</p><p>function get_page_url(){</p><p> // Find out the URL of a PHP file</p><p> $url = "http".(empty($_SERVER["HTTPS"])?"":"s")."://".$_SERVER["SERVER_NAME"];</p><p>If(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != ""){<br> $url.= $_SERVER["REQUEST_URI"];<br> }<br> else{<br> $url.= $_SERVER["PATH_INFO"];<br> }</p><p>Return $url;<br>}</p><p>function rate_limit($ip, $limit_hour = 20, $limit_10_min = 10){</p><p> // The number of login attempts for the last hour by this IP address</p><p> $count_hour = ORM::for_table("reg_login_attempt")<br> -><br> ->where_raw("ts > SUBTIME(NOW(),"1:00")")<br> ->count();</p><p> // The number of login attempts for the last 10 minutes by this IP address</p><p> $count_10_min = ORM::for_table("reg_login_attempt")<br> ->where("ip", sprintf("%u", ip2long($ip)))<br> ->where_raw("ts > SUBTIME(NOW(),"0:10")")<br> ->count();</p><p>If($count_hour > $limit_hour || $count_10_min > $limit_10_min){<br> throw new Exception("Too many login attempts!");<br> }<br>}</p><p>function rate_limit_tick($ip, $email){</p><p> // Create a new record in the login attempt table</p><p> $login_attempt = ORM::for_table("reg_login_attempt")->create();</p><p> $login_attempt->email = $email;<br> $login_attempt->ip = sprintf("%u", ip2long($ip));</p><p> $login_attempt->save();<br>}</p><p>function redirect($url){<br> header("Location: $url");<br> exit;<br>} <br>Функции rate_limit и rate_limit_tick позволяют нам ограничивать число попыток авторизации на определенный промежуток времени. Попытки авторизации записываются в базу данных reg_login_attempt. Эти функции запускаются при проведении подтверждения формы авторизации, как можно видеть в следующем фрагменте кода.</p><p>Нижеприведенный код был взят из index.php, и он отвечает за подтверждение формы авторизации. Он возвращает JSON-ответ, который управляется кодом jQuery, который мы видели в assets/js/script.js.</p><p><b>index.php </b></p><p>If(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"])){</p><p> // Output a JSON header</p><p>Header("Content-type: application/json");</p><p> // Is the email address valid?</p><p>If(!isset($_POST["email"]) || !filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)){<br> throw new Exception("Please enter a valid email.");<br> }</p><p> // This will throw an exception if the person is above <br> // the allowed login attempt limits (see functions.php for more):<br> rate_limit($_SERVER["REMOTE_ADDR"]);</p><p> // Record this login attempt<br> rate_limit_tick($_SERVER["REMOTE_ADDR"], $_POST["email"]);</p><p> // Send the message to the user</p><p> $message = "";<br> $email = $_POST["email"];<br> $subject = "Your Login Link";</p><p>If(!User::exists($email)){<br> $subject = "Thank You For Registering!";<br> $message = "Thank you for registering at our site!\n\n";<br> }</p><p> // Attempt to login or register the person<br> $user = User::loginOrRegister($_POST["email"]);</p><p> $message.= "You can login from this URL:\n";<br> $message.= get_page_url()."?tkn=".$user->generateToken()."\n\n";</p><p> $message.= "The link is going expire automatically after 10 minutes.";</p><p> $result = send_email($fromEmail, $_POST["email"], $subject, $message);</p><p>If(!$result){<br> throw new Exception("There was an error sending your email. Please try again.");<br> }</p><p>Die(json_encode(array(<br> "message" => "Thank you! We\"ve sent a link to your inbox. Check your spam folder as well."<br>)));<br> }<br>}<br>catch(Exception $e){</p><p>Die(json_encode(array(<br> "error"=>1,<br> "message" => $e->getMessage()<br>)));<br>} <br>При успешной авторизации или регистрации, вышеприведенный код отсылает email человеку с ссылкой для авторизации. Token (лексема) становится доступной в качестве $_GET-переменной "tkn" ввиду сгенерированного URL.</p><p><b>index.php </b></p><p>If(isset($_GET["tkn"])){</p><p> // Is this a valid login token?<br> $user = User::findByToken($_GET["tkn"]);</p><p> // Yes! Login the user and redirect to the protected page.</p><p> $user->login();<br> redirect("protected.php");<br> }</p><p> // Invalid token. Redirect back to the login form.<br> redirect("index.php");<br>} <br>Запуск $user->login() создаст необходимые переменные для сессии, что позволит пользователю оставаться авторизованным при последующих входах.</p><p>Выход из системы реализуется примерно таким же образом:</p><p><b>Index.php </b></p><p>If(isset($_GET["logout"])){</p><p> $user = new User();</p><p>If($user->loggedIn()){<br> $user->logout();<br> }</p><p>Redirect("index.php");<br>} <br>В конце кода мы снова перенаправляем пользователя на index.php, поэтому параметр?logout=1 в URL исключается.</p><p>Нашему файлу index.php также потребуется защита – мы не хотим, чтобы уже авторизованные пользователи видели форму. Для этого мы используем метод $user->loggedIn():</p><p><b>Index.php </b></p><p> $user = new User();</p><p>if($user->loggedIn()){<br> redirect("protected.php");<br>} <br>Наконец, давайте посмотрим, как можно защитить страницу вашего сайта, и сделать ее доступной только после авторизации:</p><p><b>protected.php </b></p><p> // To protect any php page on your site, include main.php<br>// and create a new User object. It"s that simple!</p><p>require_once "includes/main.php";</p><p>$user = new User();</p><p>if(!$user->loggedIn()){<br> redirect("index.php");<br>} <br>После этой проверки вы можете быть уверены в том, что пользователь успешно авторизовался. У вас также будет доступ к данным, которые хранятся в базе данных в качестве свойств объекта $user. Чтобы вывести email пользователя и их ранг, воспользуйтесь следующим кодом:</p><p>Echo "Your email: ".$user->email;<br>echo "Your rank: ".$user->rank(); <br>Здесь rank() – это метод, так как колонка rank в базе данных обычно содержит числа (0 для обычных пользователей и 1 для администраторов), и нам нужно преобразовать это все в названия рангов, что реализуется при помощи данного метода. Чтобы преобразовать обычного пользователя в администратора, просто отредактируйте запись о пользователе в phpmyadmin (либо в любой другой программе по работе с базами данных). Будучи администратором, пользователь не будет наделен какими-то особыми возможностями. Вы сами в праве выбирать, каким правами наделять администраторов.</p><p><b>Готово! </b> </p><p>На этом наша простенькая система регистрации готова! Вы можете использовать ее на уже существующем PHP-сайте, либо модернизировать ее, придерживаясь собственных требований.</p> <i> </i> <p>В этой статье вы узнаете, <b>как создать форму регистрации и авторизации </b>, используя HTML, JavaScript, PHP и MySql. Такие формы используются почти на каждом сайте, в независимости от его типа. Они создаются и для форума, и для интернета магазина и для социальных сетей (такие как например Facebook, Twiter, Odnoklassniki) и для многих других типов сайтов.</p> <p>Если у Вас сайт на локальном компьютере, то я надеюсь, что у Вас уже <b>установлен и запущен локальный сервер </b>. Без него ничего работать не будет.</p> <h2>Создание таблицы в Базе Данных</h2> <p>Для того чтобы реализовать регистрацию пользователей, в первую очередь нам нужна База Данных. Если она у Вас уже есть, то замечательно, иначе, Вам нужно её создавать. В статье , я подробно объясняю, как сделать это.</p> <p>И так, у нас есть База Данных (сокращённо БД), теперь нам нужно создать таблицу <i>users </i> в которой будем добавлять наших зарегистрированных пользователей.</p> <p>Как создавать таблицу в БД, я также объяснил в статье . Перед тем как создать таблицу, нам необходимо определить какие поля она будет содержать. Эти поля будут соответствовать полям из формы регистрации.</p> <p>Значит, подумали, представили какие поля будут у нашей формы и создаём таблицу <i>users </i> с такими полями:</p> <ul><li><i>id </i> - Идентификатор. Поле <i>id </i> должно быть у каждой таблицы из БД.</li> <li><i>first_name </i> - Для сохранений имени.</li> <li><i>last_name </i> - Для сохранений фамилии.</li> <li><i>email </i> - Для сохранений почтового адреса. E-mail мы будем использовать в качестве логина, поэтому это поле должна быть уникальной, то есть иметь индекс UNIQUE.</li> <li><i>email_status </i> - Поле для указания, подтверждена ли почта или нет. Если почта подтверждена, то оно будет иметь значение 1, иначе значение 0. </li> <li><i>password </i> - Для сохранений пароля.</li> </ul><p> <br><img src='https://i0.wp.com/sozdatisite.ru/images/img-articles/struktura-tablicy-users.jpg' width="100%" loading=lazy></p> <p>Если Вы хотите чтобы Ваша форма регистрации имела ещё какие-то поля, то Вы можете их здесь также добавить.</p> <p>Всё, наша таблица <i>users </i> готова. Переходим к следующему этапу.</p> <h2>Подключение к Базе Данных</h2> <p>Базу данных мы создали, теперь необходимо к ней подключиться. Подключение будем осуществлять с помощью PHP расширения MySQLi.</p> <p>В папке нашего сайта, создаём файл с именем <i>dbconnect.php </i>, и в нём пишем следующий скрипт:</p><p> <?php // Указываем кодировку header("Content-Type: text/html; charset=utf-8"); $server = "localhost"; /* имя хоста (уточняется у провайдера), если работаем на локальном сервере, то указываем localhost */ $username = "имя_пользователя_бд"; /* Имя пользователя БД */ $password = "пароль_пользователя_бд"; /* Пароль пользователя, если у пользователя нет пароля то, оставляем пустым */ $database = "имя_базы_данных"; /* Имя базы данных, которую создали */ // Подключение к базе данный через MySQLi $mysqli = new mysqli($server, $username, $password, $database); // Проверяем, успешность соединения. if (mysqli_connect_errno()) { echo "<p><strong>Ошибка подключения к БД</strong>. Описание ошибки: ".mysqli_connect_error()."</p>"; exit(); } // Устанавливаем кодировку подключения $mysqli->set_charset("utf8"); //Для удобства, добавим здесь переменную, которая будет содержать название нашего сайта $address_site = "http://testsite.local"; ?> </p><p>Этот файл <i>dbconnect.php </i> нужно будет подключить к обработчикам форм.</p> <p>Обратите внимание на переменную <i>$address_site </i>, здесь я указал название моего тестового сайта, над которым буду работать. Вы соответственно, укажите название Вашего сайта.</p> <h2>Структура сайта</h2> <p>Теперь давайте разберёмся с HTML структурой нашего сайта.</p> <p>Шапку и подвал сайта вынесем в отдельные файлы, <i>header.php </i> и <i>footer.php </i>. Их будем подключать на всех страницах. А именно на главной (файл <i>index.php </i>), на страницу с формой регистрации (файл <i>form_register.php </i>) и на страницу с формой авторизации (файл <i>form_auth.php </i>).</p> <p>Блок с нашими ссылками, <i>регистрация </i> и <i>авторизация </i>, добавим в шапку сайта, чтобы они отображались на всех страницах. Одна ссылка будет ввести на <b>страницу с формой регистрации </b> (файл <i>form_register.php </i>) а другая на страницу с <b>формой авторизации </b> (файл <i>form_auth.php </i>).</p> <p>Содержимое файла header.php:</p><p> <?php //Запускаем сессию session_start(); ?> <!DOCTYPE html> <html> <head> Название нашего сайта <link rel="stylesheet" type="text/css" href="css/styles.css"> </head> <body> </p><p>В итоге, главная страница, у нас выглядит так:</p> <p> <br><img src='https://i0.wp.com/sozdatisite.ru/images/img-articles/vid-glavnoj-stranicy.jpg' width="100%" loading=lazy></p> <p>Конечно, у Вас на сайте может быть совсем другая структура, но это для нас сейчас не важно. Главное, чтобы присутствовали ссылки (кнопки) регистрации и авторизации.</p> <h2></h2> <p>Теперь перейдём к форме регистрации. Как Вы уже поняли, она у нас находится в файле <i>form_register.php </i>.</p> <p>Идём в Базу Данных (в phpMyAdmin), открываем структуру таблицы <i>users </i> и смотрим какие поля нам нужны. Значит, нам нужны поля для ввода имени и фамилии, поле для ввода почтового адреса(Email) и поле для ввода пароля. И ещё в целях безопасности добавим поле для ввода капчи.</p> <p>На сервере, в результате обработки формы регистрации, могут возникнуть различные ошибки, из-за которых пользователь не сможет зарегистрироваться. Поэтому для того чтобы пользователь понимал почему не проходит регистрация, необходимо вывести ему сообщения об этих ошибках.</p> <p>Перед выводом формы добавляем блок для вывода сообщений об ошибках из сессии.</p> <p>И ещё момент, если пользователь уже авторизован, и он ради интереса заходит на страницу регистрации напрямую, написав в адресную строку браузера <i>адрес_сайта/form_register.php </i>, то мы в этом случае вместо формы регистрации, выведем ему заголовок о том, что он уже зарегистрирован.</p> <p>В общем, код файла <i>form_register.php </i> у нас получился таким:</p><p> <?php //Подключение шапки require_once("header.php"); ?> </p><p> <?php //Если в сессии существуют сообщения об ошибках, то выводим их if(isset($_SESSION["error_messages"]) && !empty($_SESSION["error_messages"])){ echo $_SESSION["error_messages"]; //Уничтожаем чтобы не выводились заново при обновлении страницы unset($_SESSION["error_messages"]); } //Если в сессии существуют радостные сообщения, то выводим их if(isset($_SESSION["success_messages"]) && !empty($_SESSION["success_messages"])){ echo $_SESSION["success_messages"]; //Уничтожаем чтобы не выводились заново при обновлении страницы unset($_SESSION["success_messages"]); } ?></p><p> <?php //Проверяем, если пользователь не авторизован, то выводим форму регистрации, //иначе выводим сообщение о том, что он уже зарегистрирован if(!isset($_SESSION["email"]) && !isset($_SESSION["password"])){ ?> </p><p> <?php }else{ ?> </p><h2>Вы уже зарегистрированы</h2><p> <?php } //Подключение подвала require_once("footer.php"); ?> </p><p>В браузере, страница с формой регистрации выглядит так:</p> <p> <br><img src='https://i1.wp.com/sozdatisite.ru/images/img-articles/forma-registracii.jpg' width="100%" loading=lazy></p> <p>С помощью <b>атрибута required </b>, мы сделали все поля обязательными к заполнению.</p> <p>Обратите внимание на код формы регистрации где <b>выводится капча </b>:</p><p> <img src='https://i1.wp.com/captcha.php' loading=lazy> <br></p><p>Мы в значение атрибута src для изображения, указали путь к файлу <i>captcha.php </i>, который генерирует данную капчу.</p> <p>Посмотрим на код файла <i>captcha.php </i>:</p><p> <?php session_start(); // Генерируем случайное число. $rand = mt_rand(1000, 9999); // Сохраняем значение переменной $rand (капчи) в сессию $_SESSION["rand"] = $rand; //создаём новое черно-белое изображение $im = imageCreateTrueColor(90,50); // Указываем белый цвет для текста $c = imageColorAllocate($im, 255, 255, 255); // Записываем полученное случайное число на изображение imageTtfText($im, 20, -10, 10, 30, $c, "fonts/verdana.ttf", $rand); header("Content-type: image/png"); // Выводим изображение imagePng($im); //Освобождаем ресурсы imageDestroy($im); ?> </p><p>Код хорошо закомментирован, поэтому я остановлюсь только на одном моменте.</p> <p>Внутри функции <i>imageTtfText() </i>, указан путь к шрифту <i>verdana.ttf </i>. Так вот для корректной работы капчи, мы должны создать папку <i>fonts </i>, и поместить туда файл шрифта <i>verdana.ttf </i>. Его Вы можете найти и скачать из интернета, или взять из архива с материалами данной статьи .</p> <p>С HTML структурой мы закончили, пора двигаться дальше.</p> <h2>Проверка email на валидность с помощью jQuery</h2> <p>Любая форма нуждается в проверки на валидность введённых данных, как на стороне клиента (с помощью JavaScript, jQuery), так и на стороне сервера.</p> <p>Особенную внимательность мы должны уделить полю Email. Очень важно чтобы введённый почтовый адрес был валидным.</p> <p>Для данного поля input, мы задали тип email (type="email"), это нас немножко предостерегает от неправильных форматов. Но, этого недостаточно, потому что через инспектор кода, которого предоставляет нам браузер, можно легко изменить значение атрибута <i>type </i> с <i>email </i> на <i>text </i>, и всё, наша проверка будет уже недействительна.</p> <p> <br><img src='https://i2.wp.com/sozdatisite.ru/images/img-articles/tip-polya-email.jpg' width="100%" loading=lazy></p> <p>И в таком случае, мы должны сделать более надёжную проверку. Для этого, воспользуемся библиотекой jQuery от JavaScript.</p> <p>Для подключения библиотеки jQuery, в файле <i>header.php </i>между тегами <i><head></head> </i>, перед закрывающего тега <i></head> </i>, добавляем эту строчку:</p> <p>Сразу после этой строчки, добавим код проверки валидации email. Здесь же добавим код проверки длины введённого пароля. Его длина должна быть не меньше 6 символов.</p> <p>С помощью данного скрипта, мы проверяем введённого почтового адреса на валидность. Если пользователь ввёл неправильный Email, то мы выводим ему ошибку об этом и дезактивируем кнопку отправки формы. Если всё хорошо, то мы убираем ошибку и активируем кнопку отправки формы.</p> <p>И так, с проверкой формы на клиентской части мы закончили. Теперь мы можем отправить её на сервер, где также сделаем пару проверок и добавим данные в БД.</p> <h2>Регистрация пользователя</h2> <p>Форму мы отправляем на обработку файлу <i>register.php </i>, через метод POST. Название данного файла обработчика, указано в значение атрибута <i>action </i>. А метод отправки указано в значение атрибута <i>method </i>.</p> <p>Открываем этот файл <i>register.php </i> и первое что нам нужно сделать, это написать функцию запуска сессии и подключить созданный нами ранее файл <i>dbconnect.php </i> (В этом файле мы сделали подключение к БД). И ещё, сразу объявим ячейки <i>error_messages </i> и <i>success_messages </i> в глобальном массиве сессии. В <i>error_mesages </i> будем записывать все сообщения об ошибках возникающие при обработке формы, а в <i>succes_messages </i>, будем записывать радостные сообщения.</p><p> <?php //Запускаем сессию session_start(); //Добавляем файл подключения к БД require_once("dbconnect.php"); //Объявляем ячейку для добавления ошибок, которые могут возникнуть при обработке формы. $_SESSION["error_messages"] = ""; //Объявляем ячейку для добавления успешных сообщений $_SESSION["success_messages"] = ""; ?> </p><p>Перед тем как продолжить, мы должны проверить, <b>была ли вообще отправлена форма </b>. Злоумышленник, может посмотреть на значение атрибута <i>action </i> из формы, и узнать какой файл занимается обработкой данной формы. И ему может прийти в голову мысль перейти напрямую в этот файл, набирая в адресной строке браузера такой адрес: <i>http://арес_сайта/register.php </i></p> <p>Поэтому нам нужно проверить наличие ячейки в глобальном массиве POST, имя которой соответствует имени нашей кнопки "Зарегистрироваться" из формы. Таким образом мы проверяем была ли нажата кнопка "Зарегистрироваться" или нет.</p> <p>Если злоумышленник попытается перейти напрямую в этот файл, то он получить сообщение об ошибке. Напоминаю, что переменная $address_site содержит название сайта и оно было объявлено в файле <i>dbconnect.php </i>.</p><p> <?php /* Проверяем была ли отправлена форма, то есть была ли нажата кнопка зарегистрироваться. Если да, то идём дальше, если нет, то выведем пользователю сообщение об ошибке, о том что он зашёл на эту страницу напрямую. */ if(isset($_POST["btn_submit_register"]) && !empty($_POST["btn_submit_register"])){ // (1) Место для следующего куска кода }else{ exit("<p><strong>Ошибка!</strong> главную страницу .</p>"); } ?> </p> <p>Значение капчи в сессии было добавлено при её генерации, в файле <i>captcha.php </i>. Для напоминания покажу ещё раз этот кусок кода из файла <i>captcha.php </i>, где добавляется значение капчи в сессию:</p><p> <?php session_start(); // Генерируем случайное число. $rand = mt_rand(1000, 9999); // Сохраняем значение переменной $rand (капчи) в сессию $_SESSION["rand"] = $rand; ?> </p><p>Теперь приступим к самой проверке. В файле <i>register.php </i>, внутри блока if, где проверяем была ли нажата кнопка "Зарегистрироваться", а точнее где указан комментарий "<i> // (1) Место для следующего куска кода </i>" пишем:</p><p> //Проверяем полученную капчу //Обрезаем пробелы с начала и с конца строки $captcha = trim($_POST["captcha"]); if(isset($_POST["captcha"]) && !empty($captcha)){ //Сравниваем полученное значение с значением из сессии. if(($_SESSION["rand"] != $captcha) && ($_SESSION["rand"] != "")){ // Если капча не верна, то возвращаем пользователя на страницу регистрации, и там выведем ему сообщение об ошибке что он ввёл неправильную капчу. $error_message = "<p class="mesage_error"><strong>Ошибка!</strong> Вы ввели неправильную капчу </p>"; // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] = $error_message; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } // (2) Место для следующего куска кода }else{ //Если капча не передана либо оно является пустой exit("<p><strong>Ошибка!</strong> Отсутствует проверечный код, то есть код капчи. Вы можете перейти на главную страницу .</p>"); } </p><p>Далее, нам нужно обрабатывать полученные данные, из массива POST. Первым делом, нам нужно проверить содержимое глобального массива POST, то есть находится ли там ячейки, имена которых соответствуют именам полей input из нашей формы.</p> <p>Если ячейка существует, то обрезаем пробелы с начала и с конца строки из этой ячейки, иначе, перенаправляем пользователя обратно на страницу с формой регистрации.</p> <p>Далее, после того как обрезали пробелы, добавляем строку в переменную и проверяем эту переменную на пустоту, если она не является пустой, то идём дальше, иначе перенаправляем пользователя обратно на страницу с формой регистрации.</p> <p>Этот код вставляем в указанное место "<i>// (2) Место для следующего куска кода </i>".</p><p> /* Проверяем если в глобальном массиве $_POST существуют данные отправленные из формы и заключаем переданные данные в обычные переменные.*/ if(isset($_POST["first_name"])){ //Обрезаем пробелы с начала и с конца строки $first_name = trim($_POST["first_name"]); //Проверяем переменную на пустоту if(!empty($first_name)){ // Для безопасности, преобразуем специальные символы в HTML-сущности $first_name = htmlspecialchars($first_name, ENT_QUOTES); }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error">Укажите Ваше имя</p><p class="mesage_error">Отсутствует поле с именем</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } if(isset($_POST["last_name"])){ //Обрезаем пробелы с начала и с конца строки $last_name = trim($_POST["last_name"]); if(!empty($last_name)){ // Для безопасности, преобразуем специальные символы в HTML-сущности $last_name = htmlspecialchars($last_name, ENT_QUOTES); }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error">Укажите Вашу фамилию</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error">Отсутствует поле с фамилией</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } if(isset($_POST["email"])){ //Обрезаем пробелы с начала и с конца строки $email = trim($_POST["email"]); if(!empty($email)){ $email = htmlspecialchars($email, ENT_QUOTES); // (3) Место кода для проверки формата почтового адреса и его уникальности }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error">Укажите Ваш email</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error"></p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } if(isset($_POST["password"])){ //Обрезаем пробелы с начала и с конца строки $password = trim($_POST["password"]); if(!empty($password)){ $password = htmlspecialchars($password, ENT_QUOTES); //Шифруем папроль $password = md5($password."top_secret"); }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error">Укажите Ваш пароль</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error"></p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } // (4) Место для кода добавления пользователя в БД </p><p>Особенную важность имеет поле <i>email </i>. Мы должны проверить формат полученного почтового адреса и его уникальность в БД. То есть не зарегистрирован ли уже какой-то пользователь с таким же почтовым адресом.</p> <p>В указанном месте "<i>// (3) Место кода для проверки формата почтового адреса и его уникальности </i>" добавляем следующий код:</p><p> //Проверяем формат полученного почтового адреса с помощью регулярного выражения $reg_email = "/^**@(+(*+)*\.)++/i"; //Если формат полученного почтового адреса не соответствует регулярному выражению if(!preg_match($reg_email, $email)){ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Вы ввели неправельный email</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } //Проверяем нет ли уже такого адреса в БД. $result_query = $mysqli->query("SELECT `email` FROM `users` WHERE `email`="".$email."""); //Если кол-во полученных строк ровно единице, значит пользователь с таким почтовым адресом уже зарегистрирован if($result_query->num_rows == 1){ //Если полученный результат не равен false if(($row = $result_query->fetch_assoc()) != false){ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Пользователь с таким почтовым адресом уже зарегистрирован</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Ошибка в запросе к БД</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); } /* закрытие выборки */ $result_query->close(); //Останавливаем скрипт exit(); } /* закрытие выборки */ $result_query->close(); </p><p>И так, мы закончили со всеми проверками, пора добавить пользователя в БД. В указанном месте " <i>// (4) Место для кода добавления пользователя в БД </i>" добавляем следующий код:</p><p> //Запрос на добавления пользователя в БД $result_query_insert = $mysqli->query("INSERT INTO `users` (first_name, last_name, email, password) VALUES ("".$first_name."", "".$last_name."", "".$email."", "".$password."")"); if(!$result_query_insert){ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Ошибка запроса на добавления пользователя в БД</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); }else{ $_SESSION["success_messages"] = "<p class="success_message">Регистрация прошла успешно!!! <br />Теперь Вы можете авторизоваться используя Ваш логин и пароль.</p>"; //Отправляем пользователя на страницу авторизации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); } /* Завершение запроса */ $result_query_insert->close(); //Закрываем подключение к БД $mysqli->close(); </p><p>Если в запросе на добавления пользователя в БД произошла ошибка, мы добавляем сообщение об этой ошибке в сессию и возвращаем пользователя на страницу регистрации.</p> <p>Иначе, если все прошло хорошо, в сессию мы также добавляем сообщение, но уже более приятна, а именно говорим пользователю что регистрация прошла успешно. И перенаправляем его уже на страницу с формой авторизации.</p> <h2></h2> <p>Скрипт для проверки формата почтового адреса и длины пароля находится в файле <i>header.php </i>, поэтому он будет действовать и на поля из этой формы.</p> <p>Запуск сессии также происходит в файле <i>header.php </i>, поэтому в файле <i>form_auth.php </i> сессию запускать не нужно, потому что получим ошибку.</p> <p> <?php //Подключение шапки require_once("header.php"); ?> </p><p> <?php if(isset($_SESSION["error_messages"]) && !empty($_SESSION["error_messages"])){ echo $_SESSION["error_messages"]; //Уничтожаем чтобы не появилось заново при обновлении страницы unset($_SESSION["error_messages"]); } if(isset($_SESSION["success_messages"]) && !empty($_SESSION["success_messages"])){ echo $_SESSION["success_messages"]; //Уничтожаем чтобы не появилось заново при обновлении страницы unset($_SESSION["success_messages"]); } ?></p><p> <?php //Проверяем, если пользователь не авторизован, то выводим форму авторизации, //иначе выводим сообщение о том, что он уже авторизован if(!isset($_SESSION["email"]) && !isset($_SESSION["password"])){ ?> </p> <p> <br><img src='https://i1.wp.com/sozdatisite.ru/images/img-articles/forma-avtorizacii.jpg' width="100%" loading=lazy></p> <p>Как я уже сказал, скрипт проверки формата почтового адреса и длины пароля здесь также действует. Поэтому если пользователь введёт неправильный почтовый адрес или короткий пароль, то он сразу же получить сообщение об ошибке. А кнопка <i>войти </i> станет не активной.</p> <p> <img src='https://i0.wp.com/sozdatisite.ru/images/img-articles/proverka-formy-avtorizacii.jpg' height="356" width="358" loading=lazy></p> <p>После устранения ошибок кнопка <i>войти </i> становится активной, и пользователь сможет отправить форму на сервер, где она будет обрабатываться.</p> <h2>Авторизация пользователя</h2> <p>В значение атрибута <i>action </i> у форы авторизации указан файл <i>auth.php </i>, это значит, что форма будет обрабатываться именно в этом файле.</p> <p>И так, открываем файл <i>auth.php </i> и пишем код для обработки формы авторизации. Первое что нужно сделать это запустить сессию и подключить файл <i>dbconnect.php </i> для соединения с БД.</p><p> <?php //Запускаем сессию session_start(); //Добавляем файл подключения к БД require_once("dbconnect.php"); </p><p> //Объявляем ячейку для добавления ошибок, которые могут возникнуть при обработке формы. $_SESSION["error_messages"] = ""; //Объявляем ячейку для добавления успешных сообщений $_SESSION["success_messages"] = ""; </p><p> /* Проверяем была ли отправлена форма, то есть была ли нажата кнопка Войти. Если да, то идём дальше, если нет, то выведем пользователю сообщение об ошибке, о том что он зашёл на эту страницу напрямую. */ if(isset($_POST["btn_submit_auth"]) && !empty($_POST["btn_submit_auth"])){ //(1) Место для следующего куска кода }else{ exit("<p><strong>Ошибка!</strong> Вы зашли на эту страницу напрямую, поэтому нет данных для обработки. Вы можете перейти на главную страницу .</p>"); } </p><p> //Проверяем полученную капчу if(isset($_POST["captcha"])){ //Обрезаем пробелы с начала и с конца строки $captcha = trim($_POST["captcha"]); if(!empty($captcha)){ //Сравниваем полученное значение с значением из сессии. if(($_SESSION["rand"] != $captcha) && ($_SESSION["rand"] != "")){ // Если капча не верна, то возвращаем пользователя на страницу авторизации, и там выведем ему сообщение об ошибке что он ввёл неправильную капчу. $error_message = "<p class="mesage_error"><strong>Ошибка!</strong> Вы ввели неправильную капчу </p>"; // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] = $error_message; //Возвращаем пользователя на страницу авторизации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } }else{ $error_message = "<p class="mesage_error"><strong>Ошибка!</strong> Поле для ввода капчи не должна быть пустой. </p>"; // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] = $error_message; //Возвращаем пользователя на страницу авторизации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } //(2) Место для обработки почтового адреса //(3) Место для обработки пароля //(4) Место для составления запроса к БД }else{ //Если капча не передана exit("<p><strong>Ошибка!</strong> Отсутствует проверочный код, то есть код капчи. Вы можете перейти на главную страницу .</p>"); } </p><p>Если пользователь ввёл проверочный код правильно, то идём дальше, иначе возвращаем его на страницу авторизации.</p> <h3>Проверка почтового адреса</h3> <p> //Обрезаем пробелы с начала и с конца строки $email = trim($_POST["email"]); if(isset($_POST["email"])){ if(!empty($email)){ $email = htmlspecialchars($email, ENT_QUOTES); //Проверяем формат полученного почтового адреса с помощью регулярного выражения $reg_email = "/^**@(+(*+)*\.)++/i"; //Если формат полученного почтового адреса не соответствует регулярному выражению if(!preg_match($reg_email, $email)){ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Вы ввели неправильный email</p>"; //Возвращаем пользователя на страницу авторизации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Поле для ввода почтового адреса(email) не должна быть пустой.</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Останавливаем скрипт exit(); } }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Отсутствует поле для ввода Email</p>"; //Возвращаем пользователя на страницу авторизации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } //(3) Место для обработки пароля </p><p>Если пользователь ввёл почтовый адрес в неправильном формате или значение поля почтового адреса является пустой, то мы возвращаем его на страницу авторизации где выводим ему сообщение об этом.</p> <h3>Проверка пароля</h3> <p>Следующее поле для обработки, это поле с паролем. В указанное место "<i>//(3) Место для обработки пароля </i>", пишем:</p><p>If(isset($_POST["password"])){ //Обрезаем пробелы с начала и с конца строки $password = trim($_POST["password"]); if(!empty($password)){ $password = htmlspecialchars($password, ENT_QUOTES); //Шифруем пароль $password = md5($password."top_secret"); }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Укажите Ваш пароль</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Отсутствует поле для ввода пароля</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } </p><p>Здесь мы с помощью функции md5() шифруем полученный пароль, так как в БД пароли у нас находятся именно в зашифрованном виде. Дополнительное секретное слово в шифровании, в нашем случае "<i>top_secret </i>" должна быть та которая использовалась и при регистрации пользователя.</p> <p>Теперь необходимо сделать запрос к БД на выборке пользователя у которого почтовый адрес равен полученному почтовому адресу и пароль равен полученному паролю.</p><p> //Запрос в БД на выборке пользователя. $result_query_select = $mysqli->query("SELECT * FROM `users` WHERE email = "".$email."" AND password = "".$password."""); if(!$result_query_select){ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Ошибка запроса на выборке пользователя из БД</p>"; //Возвращаем пользователя на страницу регистрации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); }else{ //Проверяем, если в базе нет пользователя с такими данными, то выводим сообщение об ошибке if($result_query_select->num_rows == 1){ // Если введенные данные совпадают с данными из базы, то сохраняем логин и пароль в массив сессий. $_SESSION["email"] = $email; $_SESSION["password"] = $password; //Возвращаем пользователя на главную страницу header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/index.php"); }else{ // Сохраняем в сессию сообщение об ошибке. $_SESSION["error_messages"] .= "<p class="mesage_error" >Неправильный логин и/или пароль</p>"; //Возвращаем пользователя на страницу авторизации header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Останавливаем скрипт exit(); } } </p><h2>Выход с сайта</h2> <p>И последнее что мы реализуем, это <b>процедура выхода с сайта </b>. На данный момент в шапке у нас выводятся ссылки на страницу авторизации и на страницу регистрации.</p> <p>В шапке сайта (файл <i>header.php </i>), с помощью сессии мы проверяем, авторизован ли уже пользователь. Если нет, то выводим ссылки регистрации и авторизации, в противном случае (если он авторизован) то вместо ссылок регистрации и авторизации выводим ссылку <i>Выход </i>.</p> <p>Модифицированный кусок кода из файла <i>header.php </i>:</p> <p> Регистрация</p> <p> Выход</p><p> <?php } ?></p> <p>При нажатии на ссылку выхода с сайта, мы попадаем в файл <i>logout.php </i>, где просто уничтожаем ячейки с почтовым адресом и паролем из сессии. После этого возвращаем пользователя обратно на ту страницу, на которой была нажата ссылка <i>выход </i>.</p> <p>Код файла <i>logout.php: </i></p><p> <?php //Запускаем сессию session_start(); unset($_SESSION["email"]); unset($_SESSION["password"]); // Возвращаем пользователя на ту страницу, на которой он нажал на кнопку выход. header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$_SERVER["HTTP_REFERER"]); ?> </p><p>На этом всё. Теперь Вы знаете как <b>реализовать и обрабатывать формы регистрации и авторизации </b> пользователя на своём сайте. Эти формы встречаются почти на каждом сайте, поэтому каждый программист должен знать, как их создавать.</p> <p>Ещё мы научились проверять вводимые данные, как на стороне клиента (в браузере, с помощью JavaScript, jQuery) так и на стороне сервера (с помощью языка PHP). Также мы научились <b>реализовать процедуру выхода с сайта </b>.</p> <p>Все скрипты проверены и рабочие. Архив с файлами этого маленького сайта Вы можете скачать по этой ссылке .</p> <p>В будущем я напишу статью где опишу . И ещё планирую написать статью где объясню, (без перезагрузки страницы). Так что, для того чтобы быть в курсе о выходе новых статей можете подписаться на мой сайт.</p> <p>При возникновении вопросов обращайтесь, также, если вы заметили, какую-то ошибку в статье прошу вас, сообщите, мне об этом.</p><p>План урока (Часть 5): </p><ol><li>Создаем HTML структуру для формы авторизации</li> <li>Обрабатываем полученные данные</li> <li>Выводим приветствие пользователя в шапку сайта</li> </ol><h3>Понравилась статья?</h3> <p>Очень часто новички сталкиваются с проблемой написания регистрации у себя на сайте. В этой статье я расскажу как ее сделать.<br> Распишу все пошагово. </p><p>Шаг 1. Подключение к базе данных MySQL. <br> Создадим файл db_connect.php:</p><p>Mysql_connect("localhost", "пользователь", "пароль пользователя") or die("Ошибка соединения с MySQL!");<br> mysql_select_db("база данных") or die ("Ошибка соединения с базой данных MySQL!");<br> mysql_set_charset("utf8"); // выставляем кодировку базы данных</p><p>Шаг 2. Создадим таблицу для пользователей.</p><blockquote>CREATE TABLE `users_profiles` (<br> `user_id` int(11) NOT NULL AUTO_INCREMENT,<br> `username` varchar(32) NOT NULL,<br> `password` varchar(32) NOT NULL,<br> PRIMARY KEY (`user_id`)<br>) ENGINE=MyISAM DEFAULT CHARSET=utf8; </blockquote><p>Шаг 3. Создадим файл handler.php - этот файл будет содержать проверку на авторизацию пользователя.</p><p> <?php<br> include_once "db_connect.php"; // проверяем подключение к базе данных</p><p> // проверяем заполнены ли логин и пароль в куках<br> if(!empty($_COOKIE["username"]) AND !empty($_COOKIE["password"]))<br> {<br> // ищем пользователя в таблице users_profiles, mysql_real_escape_string используем как защиту от sql injection<br> $search_user = mysql_query("SELECT * FROM `users_profiles` WHERE `username` = "".mysql_real_escape_string($_COOKIE["username"])."" AND `password` = "".mysql_real_escape_string($_COOKIE["password"]).""");<br> $user = (mysql_num_rows($search_user) == 1) ? mysql_fetch_array($search_user) : 0;<br> }<br> else<br> {<br> $user = 0;<br> }<br> ?> </p><p>Шаг 4. Пишем регистрацию.<br> Для этого создадим файл register.php и напишем в нем следующим код:</p><p> <?php<br></p><p><br> if($user) {<br><br> exit();<br> }</p><p>If (!empty($_POST["login"]) AND !empty($_POST["password"]))<br> {<br><br><br></p><p> // проверяем есть ли логин в нашей базе данных<br> if (mysql_result(mysql_query("SELECT COUNT(*) FROM `users_profiles` WHERE `username` = "".$login."" LIMIT 1;"), 0) != 0)<br> {<br> echo "Выбранный логин уже зарегистрирован!";<br> exit();<br> }<br> // заносим данные в таблицу, обратите внимание - пароль кодируем в md5<br> mysql_query("INSERT INTO `users_profiles` (`username`, `password`) VALUES ("".$login."", "".md5($password)."")");<br> echo "Вы успешно зарегистрированы!";<br> exit();<br> }<br> // форма регистрации<br> echo "<br> <form action="register.php" method="POST"><br> Логин:<br/><br> <input name="login" type="text" value="" /><br/><br> Пароль:<br/><br> <input name="password" type="text" value="" /><br/><br> <input type="submit" value="Зарегистрироваться" /><br> </form>";<br> ?> </p><p> <?php<br> include_once "handler.php"; // проверяем авторизирован ли пользователь</p><p> // если да, перенаправляем его на главную страницу<br> if($user) {<br> header ("Location: index.php");<br> exit();<br> }</p><p>If(!empty($_POST["login"]) AND !empty($_POST["password"]))<br> {<br> // фильтрируем логин и пароль<br> $login = mysql_real_escape_string(htmlspecialchars($_POST["login"]));<br> $password = mysql_real_escape_string(htmlspecialchars($_POST["password"]));</p><p> $search_user = mysql_result(mysql_query("SELECT COUNT(*) FROM `users_profiles` WHERE `username` = "".$login."" AND `password` = "".md5($password)."""), 0);<br> if($search_user == 0)<br> {<br> echo "Введенные данные неправильные или пользователь не найден.";<br> exit();<br> }<br> else<br> {<br> // заносим логин и пароль в куки<br> $time = 60*60*24; // сколько времени хранить данные в куках<br> setcookie("username", $login, time()+$time, "/");<br> setcookie("password", md5($password), time()+$time, "/");<br> echo "Вы успешно авторизировались на сайте!";<br> exit();<br> }<br> }<br> echo "<br> <form action="login.php" method="POST"><br> Логин:<br /><br> <input name="login" type="text" /><br /><br> Пароль:<br /><br> <input name="password" type="password" /><br /><br> <input type="submit" value="Авторизироваться" /><br> </form>";<br> ?> </p><p>Шаг 6. Выход пользователя. <br> Каждый юзер должен выходить из сайта, если он этого хочет. Для этого создадим файл exit.php</p><p> <?php<br> include_once "handler.php"; // проверяем авторизирован ли пользователь</p><p> // проверяем авторизацию пользователя<br> if($user) {<br> setcookie("username", "", time()-1, "/");<br> setcookie("password", "", time()-1, "/");<br> session_destroy();<br> echo "Вы успешно вышли!";<br> } else {<br> echo "Для этого действия нужно авторизироваться.";<br> }<br> ?> </p><p>Шаг 7. Создание главной страницы сайта. <br> Создадим последний файл - index.php</p><p> <?php<br> include_once "handler.php"; // проверяем авторизирован ли пользователь</p><p>If($user) {<br> // выводим информацию для пользователя<br> echo "Привет, <b>".$user["username"]."</b>!<br /><br> - Выйти<br /><br> ";<br> } else {<br> // выводим информацию для гостя<br> echo "<br> - Авторизация<br /><br> - Регистрация<br /><br> ";<br> }<br> ?> </p><p>Для настройки создайте файл.htaccess и впишите в него следующее:<br></p><blockquote>php_value register_globals 0 <br> php_value magic_quotes_gpc 0<p>Php_value zlib.output_compression 1</p><p>AddDefaultCharset UTF-8 </p></blockquote><p>Тем кому лень делать это все, качайте</p> <script>document.write("<img style='display:none;' src='//counter.yadro.ru/hit;artfast_after?t44.1;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";h"+escape(document.title.substring(0,150))+ ";"+Math.random()+ "border='0' width='1' height='1' loading=lazy>");</script> </div> </div> </article> <div id="disqus_thread"> </div> </main> </div> </div> <div class="col-md-4"> <div class="primary-sidebar widget-area" role="complementary"> <div id="search-2" class="widget widget_search"> <form role="search" method="get" class="search-form" action="/"> <label> <span class="screen-reader-text">Найти:</span> <input type="search" class="search-field" placeholder="Поиск…" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Поиск" /> </form> </div> <div id="recent-posts-2" class="widget widget_recent_entries"> <span class="widget-title">Свежие записи</span> <ul> <li> <a href="/internet/pokemon-go-chto-eto-takoe-i-kak-poimat-pokemona-sut-igry-pokemon-gou-v/">Суть игры покемон гоу В чем смысл игры с покемонами</a> </li> <li> <a href="/system-programs/v-chem-smysl-igry-pokemon-go-pokemon-go-obzor-i-gaid-po-lovle-pokemonov-v-chem/">Pokemon GO: обзор и гайд по ловле покемонов В чем заключается суть игры покемон гоу</a> </li> <li> <a href="/desktop/podborka-luchshie-servisy-dlya-hraneniya-foto-v-oblake-hranenie-fotografii-v/">Хранение фотографий в облаке Сервис для загрузки фотографий</a> </li> <li> <a href="/useful/ip-kamera-xiaomi-yi-ants-white-umnaya-kamera-nablyudeniya-kak-ya-voeval-s-kameroi-xiaomi-za/">Как я воевал с камерой Xiaomi за $25 Данные на SD карте</a> </li> <li> <a href="/advise/recepty-minecraft-kak-est-v-mainkrafte-chtoby-vyzhit-kraft-vsei-edy-v/">Как есть в "Майнкрафте", чтобы выжить?</a> </li> <li> <a href="/network-and-internet/ustanovka-rusifikatora-na-gta-san-andreas-ustanovka-rusifikatora-na-gta-san/">Установка русификатора на GTA San Andreas Скачать русский язык для гта са</a> </li> <li> <a href="/useful/grand-theft-auto-san-andreas-skiny-kak-ustanovit-skiny-v-samp/">Как установить скины в самп</a> </li> <li> <a href="/useful/kak-otklyuchit-kommentarii-vkontakte-chistim-karmu-v-instagram-ot/">Чистим карму в инстаграм от нежелательных комментариев в инстаграме Удаленные комментарии вконтакте</a> </li> </ul> </div> <div id="recent-posts-2" class="widget widget_recent_entries"> <span class="widget-title">Популярные записи</span> <ul> <li> <a href="/internet/vynosnoi-zhestkii-disk-dlya-plansheta-podklyuchenie-zhestkogo-diska-k/">Подключение жесткого диска к планшету</a> </li> <li> <a href="/advise/kak-vklyuchit-vyklyuchit-i-pomenyat-cvet-podsvetki-na-klaviature/">Как включить подсветку клавиатуры на ноутбуке asus?</a> </li> <li> <a href="/system-programs/pitanie-svetodiodov-blok-pitaniya-dlya-svetodiodov-chto-takoe-draiver/">Что такое драйвер для светодиодов и как подобрать нужный Расчет драйвера для светодиодов</a> </li> <li> <a href="/utilities/svetodiodnyi-indikator-urovnya-signala-na-lm3915-svetodiodnyi/">Светодиодный индикатор уровня сигнала Индикатор уровня аудио</a> </li> <li> <a href="/program-settings/zvezdnyi-instagram-instagram-rossiiskih-znamenitostei-kto-naibolee/">Инстаграм российских знаменитостей: кто наиболее популярен?</a> </li> <li> <a href="/program-settings/plagin-seo-by-yoast-nastroika-pravilnaya-nastroika-yoast-seo-plagina/">Правильная настройка Yoast SEO плагина для WordPress</a> </li> <li> <a href="/program-settings/poe-trebovaniya-path-of-exile-sistemnye-trebovaniya-na-pk-path-of-exile/">Path of Exile системные требования на ПК</a> </li> <li> <a href="/internet/forza-horizon-3-sistemnye-trebovaniya-minimalnye-sistemnye-trebovaniya/">Минимальные системные требования</a> </li> </ul> </div> <div id="ai_widget-2" class="widget ai_widget"> <div class='code-block code-block-5' style='margin: 8px 0; clear: both;'> </div> </div> </div> </div> <div class="col-md-4"> <div class="primary-sidebar widget-area" role="complementary"> </div> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-md-12"> <hr> </div> </div> </div> <footer class="site-footer" role="contentinfo"> <div class="container"> <div class="row"> <div class="col-sm-12 text-center"> <p></p> <div class="footer-social-icons"> <a href="/feedback/">Контакты</a> | <a href="/sitemap.xml">Карта сайта</a> </div> </div> </div> </div> </footer> <div class="scroll-up"> <a href="#"><i class="fa fa-angle-up"></i></a> </div> <script type="text/javascript">jQuery(function($) { $(document).on("click", ".pseudo-link", function(){ window.open($(this).data("uri")); } );} );</script><script type='text/javascript' src='https://ppu-app.ru/wp-content/plugins/table-of-contents-plus/front.min.js?ver=1509'></script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/themes/onlineelektrik/assets/js/bootstrap.min.js?ver=3.3.5'></script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/themes/onlineelektrik/assets/js/scripts.js'></script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/themes/onlineelektrik/assets/js/jquery.fitvids.js'></script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/themes/onlineelektrik/assets/js/smoothscroll.js'></script> <script type='text/javascript' src='/wp-includes/js/comment-reply.min.js?ver=4.8.4'></script> <script type='text/javascript'> var q2w3_sidebar_options = new Array(); q2w3_sidebar_options[0] = { "sidebar" : "shaped-blog-sidebar", "margin_top" : 10, "margin_bottom" : 1000, "stop_id" : "", "screen_max_width" : 0, "screen_max_height" : 0, "width_inherit" : false, "refresh_interval" : 1500, "window_load_hook" : false, "disable_mo_api" : false, "widgets" : ['ai_widget-2'] } ; </script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/plugins/q2w3-fixed-widget/js/q2w3-fixed-widget.min.js?ver=5.0.4'></script> <script type='text/javascript' src='/wp-includes/js/wp-embed.min.js?ver=4.8.4'></script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/plugins/disqus-comment-system/media/js/disqus.js?ver=4.8.4'></script> <script type='text/javascript' src='https://ppu-app.ru/wp-content/plugins/disqus-comment-system/media/js/count.js?ver=4.8.4'></script> </body> </html>