Первым делом требуется создать серверный файл .htaccess, в нем происходит присвоение сайту кодировки, запуск движка и установка правил.
AddDefaultCharset utf-8
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
Последней строкой мы исполняем правила и перенаправляем пользователя в файл index.php. Его также нужно создать в директории с .htaccess.
Index.php является главным контроллером и содержит следующий код:
Отключаем отображение всех ошибок:
<?php ini_set('display_errors',0); ?>
Запускаем сессию. Так она будет всегда запущена и не будет нужды каждый раз ее запускать:
<? session_start(); ?>
Подгружаем файлы системы:
<?
define('ROOT', dirname(__FILE__));
require_once(ROOT.'/components/Autoload.php');
?>
Вызываем роутер:
<?
$router = new Router();
$router->run();
?>
Теперь создадим сам Router. Для этого создаем новую директорию с названием components и в нем создаем файл Router.php. Он будет содержать следующий код:
<?
/**
* Класс Router
* Компонент для работы с маршрутами
*/
class Router
{
/**
* Свойство для хранения массива роутов
* @var array
*/
private $routes;
/*** Конструктор*/
public function __construct()
{
// Путь к файлу с роутами
$routesPath = ROOT . '/config/routes.php';
// Получаем роуты из файла
$this->routes = include($routesPath);
}
/*** Возвращает строку запроса*/
private function getURI()
{
if (!empty($_SERVER['REQUEST_URI'])) {
return trim($_SERVER['REQUEST_URI'], '/');
}
}
/*** Метод для обработки запроса */
public function run()
{
// Получаем строку запроса
$uri = $this->getURI();
// Проверяем наличие такого запроса в массиве маршрутов (routes.php)
foreach ($this->routes as $uriPattern => $path) {
// Сравниваем $uriPattern и $uri
if (preg_match("~$uriPattern~", $uri)) {
// Получаем внутренний путь из внешнего согласно правилу.
$internalRoute = preg_replace("~$uriPattern~", $path, $uri);
// Определить контроллер, action, параметры
$segments = explode('/', $internalRoute);
$controllerName = array_shift($segments) . 'Controller';
$controllerName = ucfirst($controllerName);
$actionName = 'action' . ucfirst(array_shift($segments));
$parameters = $segments;
// Подключить файл класса-контроллера
$controllerFile = ROOT . '/controllers/' .
$controllerName . '.php';
if (file_exists($controllerFile)) {
include_once($controllerFile);
}
// Создать объект, вызвать метод (т.е. action)
$controllerObject = new $controllerName;
/* Вызываем необходимый метод ($actionName) у определенного
* класса ($controllerObject) с заданными ($parameters) параметрами
*/
$result = call_user_func_array(array($controllerObject, $actionName), $parameters);
// Если метод контроллера успешно вызван, завершаем работу роутера
if ($result != null) {
break;
}
}
}
}
}
?>
Создаем файл Autoload.php он подгружает файлы системы и будет содержать следующий код:
<?
/**
* Функция __autoload для автоматического подключения классов
*/
function __autoload($class_name)
{
// Массив папок, в которых могут находиться необходимые классы
$array_paths = array(
'/components/',
'/controllers/',
);
// Проходим по массиву папок
foreach ($array_paths as $path) {
// Формируем имя и путь к файлу с классом
$path = ROOT . $path . $class_name . '.php';
// Если такой файл существует, подключаем его
if (is_file($path)) {
include_once $path;
}
}
}
?>
Создаем директорию config и в нем файл routes.php. Он будет содержать следующий путь в основном массиве путей:
<?php
return array(
'' => 'site/index', // actionIndex в SiteController
);
?>
Этим мы показываем, что когда пользователь введет в адресную строку домен сайта и после слеша ничего нет, то он автоматически попадет на главную страницу, через сайт-контролер и метод-индекс.
Далее нужно создать директорию controllers и в ней файл SiteController.php. В самом файле создадим класс SiteController.
<? class SiteController ?>
В нем создаем метод который будет направлять пользователя на вид страницы. Для этого создадим директорию views в ней директорию site, а в ней файл index.php, это будет нашим видом.
<?
/**
* Контроллер SiteController
*/
class SiteController
{
public function actionIndex()
{
require_once(ROOT . '/views/site/index.php');
return true;
}
}
?>
В файле вида index.php создадим простой код для отображения страницы:
<html>
<head>
<title>MVC</title>
</head>
<body>
<h1>Привет MVC!</h1>
</body>
</html>
Комментарии ( 1 )
Подскажите пожалуйста, почему у меня не возвращается название контроллера, при таком коде? class Router { /** * Свойство для хранения массива роутов * @var array */ private $routes; /*** Конструктор*/ public function __construct() { // Путь к файлу с роутами $routesPath = ROOT . '/config/routes.php'; // Получаем роуты из файла $this->routes = include($routesPath); } /*** Возвращает строку запроса*/ private function getURI() { if (!empty($_SERVER['REQUEST_URI'])) { return trim($_SERVER['REQUEST_URI'], '/'); } } /*** Метод для обработки запроса */ public function run() { // Получаем строку запроса $uri = $this->getURI(); // Проверяем наличие такого запроса в массиве маршрутов (routes.php) foreach ($this->routes as $uriPattern => $path) { // Сравниваем $uriPattern и $uri if (preg_match("~$uriPattern~", $uri)) { // Получаем внутренний путь из внешнего согласно правилу. $internalRoute = preg_replace("~$uriPattern~", $path, $uri); // Определить контроллер, action, параметры $segments = explode('/', $internalRoute); $controllerName = array_shift($segments) . 'Controller'; $controllerName = ucfirst($controllerName); $actionName = 'action' . ucfirst(array_shift($segments)); $parameters = $segments; выводит вот такое значение: (Newtest - это название проекта на локалке) Имя контроллера: NewtestController Экшн: actionNews Array ( [0] => view [1] => sport [2] => 229 ) routes: return array( 'news/([a-z]+)/([0-9]+)' => 'news/view/$1/$2', );
25.12.2017