Pull to refresh

«Я буду долго гнать велосипед!» История создания «своего» фреймворка

Reading time4 min
Views3.7K

Где-то около 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, попробую рассказать о их "+" и "-" на простом примере с какими проблемами я сам столкнулся и как их решил.

Спасибо, не унывайте!

Tags:
Hubs:
Total votes 5: ↑3 and ↓2+3
Comments4

Articles