
- •2.2. Изоляция представления.
- •2.3. Изоляция логики Приложения (Домена)
- •2.4. Изоляция разметки (Layout)
- •2.5. Добавляем страницу блога “show”¶
- •2.6. Front Controller
- •2.7. Создание фронт-контроллера
- •2.8. Прикосновение к Symfony2
- •2.9. Простое приложение на Symfony2
- •2.10. Преимущество Symfony2
- •2.11. Лучшие шаблоны
2.6. Front Controller
Решением указанных выше проблем является использование front controller: единственного PHP-файла, который будет обрабатывать любой запрос. При использовании front controller (далее просто фронт-контроллер) URI для вашего приложения изменяются незначительно, но становятся более гибкими:
Без фронт-контроллера
/index.php => Список постов (выполняется index.php)
/show.php => Отдельный пост (выполняется show.php)
При использовании index.php в качестве фронт-контроллера
/index.php => Список постов (выполняется index.php)
/index.php/show => Отдельный пост (выполняется index.php)
Часть URI, включающая index.php, может быть опущена при использовании rewrite rules веб-сервера Apache (или их эквивалента для прочих веб-серверов). В этом случае результирующий URI для страницы с постом блога будет просто /show.
При использовании фронт-контроллера один PHP файл (index.php в нашем случае) обрабатывает любой запрос. Для страницы с одним постом /index.php/show будет выполнять файл index.php, который теперь несёт ответственность за маршрутизацию запроса, основываясь на полном URI. Как вы скоро увидите фронт-контроллер - это очень мощный инструмент.
2.7. Создание фронт-контроллера
Внимание! Прямо сейчас вы стоите на пороге большого шага для вашего приложения. Имея один файл, который принимает все запросы, вы можете централизованно обрабатывать вопросы, связанные, к примеру, с безопасностью, загрузкой конфигурации, маршрутизацией. В нашем приложении index.php теперь должен быть достаточно умён, чтобы отобразить страницу со списком постов или страницу отельного поста, основываясь на URI запроса:
<?php
// index.php
// Загружаем и инициализируем глобальные библиотеки
require_once 'model.php';
require_once 'controllers.php';
// Внутренняя маршрутизация
$uri = $_SERVER['REQUEST_URI'];
if ($uri == '/index.php') {
list_action();
} elseif ($uri == '/index.php/show' && isset($_GET['id'])) {
show_action($_GET['id']);
} else {
header('Status: 404 Not Found');
echo '<html><body><h1>Page Not Found</h1></body></html>';
}
Для улучшения структуры приложения, оба контроллера (ранее index.php и show.php) превратились в функции, и каждая из них была помещена в файл controllers.php:
<?php
// controllers.php
function list_action()
{
$posts = get_all_posts();
require 'templates/list.php';
}
function show_action($id)
{
$post = get_post_by_id($id);
require 'templates/show.php';
}
Став фронт-контроллером, index.php получил совершенно новую роль, включая загрузку библиотек ядра и маршрутизацию, которая сейчас заключается в вызове одного из двух контроллеров (функции list_action() и show_action()). На самом деле, этот фронт-контроллер уже, в плане обработки запросов и маршрутизации, начинает себя вести сходным образом, как и контроллер Symfony2.
Другое достоинство фронт-контроллера - это гибкие URL. Обратите внимание, что URL для страницы, отображающей отдельный пост блога, в любой момент может быть изменён с /show на /read, изменив код всего лишь в одном месте. Ранее же нам бы потребовалось переименовать файл целиком. В Symfony2 URL ещё более гибки.
К этому времени, приложение разрослось с одного PHP-файла до целой структуры, которая хорошо организована и позволяет повторное использование кода. Однако, остались еще недостатки. К примеру, система “маршрутизации” ненадёжна и не может определить, что страница list (/index.php) должна быть доступна через / (если используются Apache rewrite rules). Также, вместо того чтобы разрабатывать блог, много времени было потрачено на “архитектуру” кода (например, маршрутизацию, вызовы контроллеров, шаблоны и т.п.). Еще больше времени нужно, чтобы обрабатывать отправку форм, валидацию введённых данных, логгирование и безопасность. Почему мы должны заново изобретать решения для этих рутинных проблем?