Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Где-то около 8 лет назад мне потребовалось определиться с PHP фреймворком для реализации одного проекта. Из фреймворков я знал только понаслышке zend, и ModX Revo с Bitrix. Последние-то и фреймворком трудно было назвать - это были полноценные CMS, которых на тот момент было огромное множество, и они были на пике популярности. В то время не искали разработчиков Laravel или Symfony, тогда нужны были администраторы/модераторы/разработчики Bitrix, Drupal и т.д.
И я принял тогда решение писать свой фреймворк с "0". Задача стояла простая - нужна была работа с БД и RESTful API интерфейс.
Итак - начинаем собирать двухколесный.
"Ленивому и в будни праздник"
БД
Началось, что я немного ленив и писать SQL запросы напрямую к БД мне не хотелось совсем, тем более что я "наглотался" этого в предыдущих проектах.
Это привело меня к поиску чего-то готового, и я наткнулся на тогда еще молодой фреймворк Medoo.in, и это оказалось открытием №1. Немного "доработав" фреймворк, проблема с БД была решена.
Приступаем к RESTful API интерфейсу
Что это такое? - Это просто запросы GET, POST, PUT, DELETE от клиента к серверу. Как бы не пытались вложить в это слово "REST" огромный смысл.
А как же SOAP?!
SOAP - это тот же REST интерфейс в котором передается XML по двум каналам GET и POST. И поверьте смотреть на этот формат через такую призму будет куда понятнее :)
С REST'ом были тоже различные мелкие фреймворки которые пытались мне помочь, но меня всё не устраивало. Какие-то роуты, какие-то адресации в общем - трудно, и в другой бы ситуации может быть и помогло но не в этой.
Благо у меня был опыт работы с MODX и тогда мне очень заинтересовал их подход к реализации friendly(дружественных) наименований страниц, отвечал за него небольшой файлик (.htaccess) для Apache. Коротко, со следующим содержанием:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]
Коротко о том, что здесь написано:
Если вы обращаетесь к серверу и на сервере нет такого файла или папки, запрос переадресуется в файл index.php и уже там сами разбирайтесь, что от вас хотел пользователь, при этом никаких 4хх ошибок не будет, ну если вы сами не захотите их сделать.
И запрос http://мойдомен.ру/я/хочу/что-то/необычное будет автоматически отредиректен сюда http://мойдомен.ру/index.php?q=я/хочу/что-то/необычное
И это полностью решало вопрос редиректа! Но не решало вопроса Роутинга, приступим.
Роутим!!!
С роутами мне показалось слишком сложной реализация в предыдущих фреймворках, и любому программисту должно быть сразу понятно куда "бежать", взглянув только на строку запроса, не ища её описания в огромных списках, а то и хуже в phpdocs.
В общем - роутинг банален, первое значение роута - это всегда класс для обработки, 2-е значение - это public функция. И не к чему какие-то сложности. Для исключения я придумал функцию Init в которую передаются все параметры о роуте.
Как к вам обращаются через GET, POST, и т.д. можно всегда узнать из $SERVER["METHOD"], если не унаследовались от нужного класса.
Так обращение к http://domen.com/users/list/10/30 переадресует пользователя в класс users.controller.php функция public function list($params) {}
По-моему, ничего прозрачнее придумать уже невозможно.
Собственно на этом можно было бы и остановиться, и так и было. Всё было сделано по канонам MVC - модель/выдача/контроллер - построена, но без View.
В 2-х словах о MVC кому интересно
MVC - это что-то вроде стандарта правильной разработки "программ".
Контроллер - это первое с чем "сталкивается" пользователь. Там система начинает понимать, что он неё хотят, "открыть страницу со списком пользователей", или "самоуничножиться".
Контроллер - сам не обращается к БД, для этого есть модель. И контроллер ничего не выводит на экран, для этого есть View, контроллер только подготавливает(упаковывает) данные. Если у вас в контроллере появились не дай бог прямые запросы к БД и формирование тегов html, то выйдите на улицу подышите, можете закурить, но запах клея и краски надо выветреть. Так быть не должно.
Модель - это область обращения к БД. Почему надо её выводить отдельно? Вам может пригодится позже. К примеру при смене БД или при смене колонок в таблице, вам не надо искать по всему коду все места где есть обращение к таблице, а изменить запрос или выдачу в одном месте - Модели данной таблицы.
Выдача - это часть отвечает за формирование результата работы Контроллера. На основании данных из контроллера формируется HTML, или JSON, или XML, или межгалактический стандарт! Всё зависит от того что захотите.
5 лет, система работала как часы, 250 тыс. REST запросов в сутки, независимо от версии php, от нахождения сервера, сервер не нагружался в пики и до 15% на самом слабом железе - всё работало!
Вот ссылка
Пока не захотелось в случае ошибки открывать на сервере страничку с описанием ошибки, а может быть и хелп какой...
А для этого я его не проектировал...
"Всякому овощу свое время"
В общем потребовалось открывать страницы на фреймворке для пользователей, что же делать...
И тут видимо я сам стал на себя не похож и решил, что я отлично сгожусь в роли революционера, и быстро сделаю класс для рендеринга, или как говорят "отличники" VIEW часть фреймворка.
В общем не вдаваясь в подробности существующий тогда TWIG - разбил все мои начинания в пыль! Я реализовал почти аналогию TWIGа и когда увидел его, мне потребовалось не мало мужества принять, то, что данный инструмент - в 100 раз "гибче", "удобнее", и т.д, моего.
С точки зрения ядра мне оставалось всего лишь определять что возвращает мне класс, и если он возвращал мне объект(object), то я не задумываясь, и по всем принципам SOLID (сейчас слюна у отличников потекла) отправлял его рендерить и выводить на экран!
Вот ссылка с твигом
Юхуууу! Где мой пина-колада, я отдыхать!
...
Почти
...
Как подкралось не пойми от куда, и кто его придумал - ТЕСТИРОВАНИЕ!!!
"Бага с возу - релизу легче"
Тут я даже не стал долго думать. Есть отличные инструменты по типу CODECEPTION.
Добавил через Composer - поднастроил - пользуйся! Фреймворк позволяет подключать вендорные(vendors) модули.
Если кто-то поможет настроить SILENIUM на CODECEPTION - буду рад, у меня пока не получилось.
И ссылка с Codeception
Теперь точно пошел пить свой "Куба-Либре"!
В следующий раз расскажу и сравню одно и тоже задание на 4-х популярных фреймворках - это Laravel, Symfony, Yii2 и Phalcon, попробую рассказать о их "+" и "-" на простом примере с какими проблемами я сам столкнулся и как их решил.
Спасибо, не унывайте!