До сих пор наше приложение было довольно простым, поскольку содержало только одну страницу.
Что бы немного все усложнить, добавим другую страницу, говорящую «goodbye»:

Как видите, большая часть кода точно такая же как и для первой страницы. Давайте отделим общий код для всех наших страниц. «Отделение общего кода», звучит как отличный план для нашего первого «настоящего» фреймворка!

В рамках PHP рефакторинг будет состоять из создания подключаемого файла:

Посмотрим на это в действии:

И для страницы “Goodbye“:

Итак, мы собрали общий код в одном месте. Но это не выглядит как хороший уровень абстракции, не так ли?
Во-первых, у нас все еще есть вызов метода send() на всех страницах, по-этому наши страницы не похожи на обычные шаблоны, и мы до сих пор не можем «правильно» тестировать код.

Другая серьёзная проблема заключается в том, что добавление новой страницы означает что мы должны создать новый PHP скрипт,
название которого будет передаваться в URL(http://example.com/bye.php) и вызываться веб-сервером.
Хорошей идеей будет перенести вызов нужного скрипта в наш код для лучшей гибкости.
Этого можно достичь перенаправляя все запросы в один PHP скрипт.

Перенаправление всех запросов в один скрипт это паттерн проектирования Front Controller

Сам скрипт может выглядеть так:

И пример нового hello.php:

В скрипте front.php, $map связывает пути в URL соответсвующим путям к файлам скриптов.

Как бонус, если клиент запрашивает путь, который не определен в массиве соответсвий, мы возвращаем 404 ошибку.
Теперь вы сами контролируете сайт.

Теперь для доступа к страницам вы должны использовать скрипт front controller’а front.php:

/hello и /bye это «пути» страниц.

Большинство веб-серверов, таких как Apache или nginx, способны переписывать
запрашиваемые URL страниц тем самым убирая из них название файла front controller’а (front.php),
так что вашим пользователям будет достаточно набрать example.com/hello?name=Fabien, что выглядит значительно лучше.

Итак, фокус в использовании метода Request::getPathInfo(), который возвращает часть пути из Request,
удаляя из него название файла front controller’а включая все поддиректории (только если потребуется — см. подсказку выше).

Вам даже не нужно настраивать веб-сервер. Просто замените вызов $request = Request::createFromGlobals(); на что-то типа $request = Request::create(‘/hello?name=Fabien’); где аргументом является запрос, который вы хотите имитировать.

Теперь, когда все запросы к нашим страницам идут через один скрипт (front.php),
мы можем способствовать безопасности перенеся все остальные PHP файлы вне корневой веб-директории:

Сейчас, настройте ваш веб-сервер так, что бы директория web/ была корневой для него.
Все, другие файлы больше не доступны для клиента.

Для работы данной структуры директорий, вам нужно будет изменить пути в некоторых файлах проекта;
эти изменения будут домашней работой для читателя.

Последнее, что повторяется на кажлой странице, это вызов setContent(). Сейчас мы можем превратить все наши страницы в «шаблоны» просто делая вывод контента и вызывать setContent() прямо из скрипта front controller’а:

Теперь скрипт hello.php можно переделать в шаблон:

На сегодняшний день наш фреймворк выглядит так:

Добавление страниц происходит в два шага: добавляем элемент в массив путей и создаем PHP шаблон в src/pages/. Из шаблона нам доступны данные Request посредством переменной $request и мы можем манипулировать заголовками ответа (Response) через переменную $response.

Если вы решите остановиться сейчас, хорошей идеей будет вынести массив соответсвий URL в конфигурационный файл.