
Программирование / Заочники / Высокоуровневые методы / 1. Методичка PHP
.pdf
public static function Login($email, $password)
{
try
{
$con = DBHelper::GetConnection();
// проверяем нет ли такого пользователя уже
$query = $con->prepare("SELECT * FROM `users` WHERE EMail=? AND Password=?");
$query->execute([$email, User::GetCryptedPassword($email, $password)]);
$query->setFetchMode(PDO::FETCH_CLASS, 'User'); $user = $query->fetch();
if ($user)
{
$_SESSION['logged_user'] = serialize($user); return USER_LOGGED;
}
else
{
return USER_LOGIN_FAILED;
}
}
catch(PDOException $e)
{
DBHelper::ProcessException($e);
}
return USER_ERROR;
}
public function Logout()
{
if (User::GetLoggedUser() == $this)
{
unset($_SESSION['logged_user']); session_destroy();
}
}
public function Register()
{
$this->Validate();
try
{
$con = DBHelper::GetConnection();
// проверяем нет ли такого пользователя уже
$query = $con->prepare("SELECT 1 FROM `users` WHERE
EMail=?");
$query->bindParam(1, $this->email); $query->execute();
$result = $query->fetch();
if (!$result)

{
$query = $con->prepare("INSERT INTO `users` (email, password, fname, sname, mname) VALUES(?, ?, ?, ?, ?)");
$result = $query->execute([$this->email, User::GetCryptedPassword($this->email, $this->password), $this->fname, $this->sname, $this->mname]);
if ($result)
{
return USER_REGISTERED;
}
else
{
return USER_ERROR;
}
}
else
{
return USER_ALREADY_REGISTERED;
}
}
catch(PDOException $e)
{
DBHelper::ProcessException($e);
}
return USER_ERROR;
}
}
5.
Листинг 19. User.php (файл mvc\Model\User.php)
6.Следующим шагом создадим дефолтовый контроллер. Это будет файл
DefController.php в папке Controller (листинг 20).
<?php session_start();
class DefController
{
private $data;
function __construct()
{
if (User::IsUserLogged())
$this->data['logged_user'] = User::GetLoggedUser();
}
function Render()
{
include VIEW_DIR . "default.tpl"; die();
}
}
Листинг 20. Дефолтовый контроллер(файл mvc\Controller\DefController.php)
Т.е. это будет как раз тот код, который будет выполняться когда пользователь
заходит на страницу. В конструкторе контроллера проверяется – если

пользователь авторизирован, то в переменную класса data заносится ссылка на текущего пользователя. Далее эта переменная будет использоваться в Представлении (View).
7. Далее создадим Представление(View). Представление будет представлять из себя файл с расширение tpl (от слова template), который будет включаться в код того или иного контроллера (см. метод Render).
Создайте в папке View файл default.tpl и добавьте туда код из листинга 21.
<!DOCTYPE html> <html>
<head> <title>Лабораторная</title>
<link rel="stylesheet" type="text/css" href="css/bootstrap.css"> </head>
<body>
<div class="container">
<?php if(isset($this->data['error'])): ?>
<p style="color: red"><?=$this->data['error']?></p> <?php endif; ?>
<?php if(isset($this->data['logged_user'])): ?> <p>You are logged in!</p>
<p>Your email is <?=$this->data['logged_user']->getEMail()?> </p> <p>Your FIO is <?=$this->data['logged_user']->getFIO()?></p> <form action="index.php?c=auth" method="post">
<input type="hidden" name="action" value="logout"> <input type="submit" class="btn" value="Logout">
</form> <?php else: ?>
<form action="index.php?c=auth" method="post"> <label for="email">EMail:</label>
<input id="email" type="text" name="email">
<label for="pass">Пароль: </label>
<input id="pass" type="password" name="pass">
<label for="sname">Фамилия:</label>
<input id="sname" type="text" name="sname" >
<label for="fname">Имя:</label>
<input id="fname" type="text" name="fname">
<label for="mname">Отчество:</label>
<input id="mname" type="text" name="mname"><br>
<input type="hidden" name="action" value="register">
<input type="submit" class="btn" value="Register"> </form>
<form action="index.php?c=auth" method="post"> <label for="email1">EMail:</label>
<input id="email1" type="text" name="email">

<label for="pass1">Пароль: </label>
<input id="pass1" type="password" name="pass"><br>
<input type="hidden" name="action" value="login">
<input type="submit" class="btn" value="Login"> </form>
<?php endif; ?> </div>
</body>
</html>
Листинг 21. Скрипт, обрабатывающий выход пользователя (файл sample2\logout.php)
Для более красивого отображения элементов скачайте из интернета файл bootstrap.css и добавите его в папку mvc\css.
Файл шаблона (Представления) состоит в основном из HTML кода и небольшими вставками PHP кода.В шаблоне мы имеем доступ только к переменной data, которая должна быть объявлена в классе каждого контроллера. Несмотря на то, что в этом шаблоне не подключаются никакие классы, мы имеем доступ к переменной data, так как сам шаблон включается в класс контроллера. В метод Render, функция include вставляет код того или файла, как если бы мы это делали через Ctr+C\Ctrl+V. И после этого он начинает интерпретироваться, т.е. выполняться.
8. Основные 3 компонента созданы(Model, View, Controller), осталось создать скрипт,
который будет получать все запросы от браузера (будем использовать шаблон Front
Controller), выбирать нужный контроллер и передавать ему управление.
Это будет файл index.php, который будет выполнять функции роутера.
Создайте в папке mvc файл index.php и добавьте в него код из листинга 22.
<?php
error_reporting (E_ALL);
define ('DS', DIRECTORY_SEPARATOR);
// Узнаём путь до файлов сайта
$root_site = realpath(dirname(__FILE__) . DS) . DS; define("ROOT_SITE", $root_site);
define("CONTROLLER_DIR", $root_site . "Controller" . DS); define("MODEL_DIR", $root_site . "Model" . DS); define("VIEW_DIR", $root_site . "View" . DS); define("CSS_DIR", $root_site . "css" . DS);
// автоматическая загрузка классов function my_autoloader($class)
{
$pathes = [CONTROLLER_DIR, MODEL_DIR, ROOT_SITE, VIEW_DIR];
foreach ($pathes as $path)

{
$filepath = $path . $class . '.php'; if (file_exists($filepath))
{
include $filepath; return true;
}
}
return false;
}
spl_autoload_register('my_autoloader');
$controller = isset($_REQUEST['c'])?$_REQUEST['c']:''; $controller = htmlspecialchars($controller);
if ($controller === '')
{
$ctl = new DefController(); $ctl->Render();
}
else
{
$class = $controller;
$filename = CONTROLLER_DIR . $class . '.php'; // пробуем найти такой контроллер
if (file_exists($filename))
{
try
{
$ctl = new $class($action);
// если передаётся запрос на выполенние конкретного действия if (isset($_REQUEST['action']))
{
$action_to_call = array($ctl, $_REQUEST['action']); // ищем у контроллера такой метод
if (is_callable($action_to_call))
{
// и если есть - вызываем его call_user_func($action_to_call);
}
else
{
die ("Ошибка: метод " . $_REQUEST['action'] . "не
найден");
}
}
$ctl->Render();
}
catch (Exception $e)
{
echo $e->getMessage();
}
}
else
{

echo "Ошибка: невозможно найти файл $filename" ;
}
}
Листинг 22. Роутер (файл mvc\index.php)
9.После этого шага можно запустить файл – он должен загружаться. Для того, чтобы работала регистрация и логин, нужно добавить контроллер логина\регистрации.
10.Добавим контроллер, который будет отвечать за всю работу с пользователями
(регистрацию, логин, выход). Назовём его Auth.php (листинг 23).
<?php
class Auth
{
private $data;
function Login()
{
session_start();
if (isset($_POST['email'], $_POST['pass']))
{
$email = $_POST['email']; $pass = $_POST['pass'];
if (User::Login($email, $pass) == USER_LOGGED)
{
$this->data['error'] = 'Succcess!'; $this->data['logged_user'] = User::GetLoggedUser();
}
else
{
$this->data['error'] = "Wrong email or password!";
}
}
}
function Logout()
{
session_start();
if (User::IsUserLogged())
{
User::GetLoggedUser()->Logout();
}
}
function Register()
{
try
{
if (isset($_POST['fname'], $_POST['sname'], $_POST['mname'], $_POST['email'],$_POST['pass']))
{
$user = User::Create($_POST['email'], $_POST['pass'], $_POST['fname'], $_POST['sname'], $_POST['mname']);

switch($user->Register())
{
case USER_REGISTERED:
$this->data['error'] = 'Пользователь успешно
зарегистрирован';
break;
case USER_ALREADY_REGISTERED: $this->data['error'] = "Ошибка: Пользователь c
таким email уже зарегистрирован!"; break;
case USER_ERROR:
$this->data['error'] = "Ошибка: Невозможно зарегистрировать пользователя!";
break;
}
}
}
catch (UserException $e)
{
$this->data['error'] = $e->getMessage();
}
}
function Render()
{
include VIEW_DIR . "default.tpl"; die();
}
}
Листинг 23. Auth.php(файл mvc\Controller\Auth.php)
11. Чтобы все запросы перенаправлялись на index.php, можно создать в папке mvc
файл .htaccess (в начале стоит точка) и добавить туда код из листинга 24.
.htaссess – это файл дополнительной конфигурации веб-сервера Apache.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
Листинг 24. Файл mvc\.htaccess
Самостоятельное задание 5.
Добавить в модель логику подтверждения регистрации, разработанные в Сам.
задании 3.
Усовершенствовать метод Validate (класс User), так, чтобы он соответствовал
самостоятельному заданию 2 (метод используется для проверки введённых
данных).

Приложение 1. Автозагрузка файлов на удалённый сервер.
1.Теперь добавим удалённый сервер (рисунок 5). Файлы будут передаваться по протоколу ftp.
Рисунок 5. Добавление ссылки на удалённый сервер
2.Настроим закладку Connection (рисунок 6).
FTP host может не всегда совпадать с названием сайта, это нужно уточнять в панели управления на сайте, который предоставляет вам хостинг.
Username и Password получаются так же – через панель управления на сайте
(cPanel) или приходят на почту.
Root path – корень сайта, обычно бывает public_html или htdocs.
Рисунок 6. Закладка Connection
3. Настроим закладку Mappings (рисунок 7)

Рисунок 7. Закладка Mappings