Как я решил написать ORM на php с нуля на работающем сайте, и что из этого вышло

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
Я, как и многие программисты, довольно отрицательно отношусь к созданию велосипедов и изобретению колес и это более чем обосновано хотя бы стоимостью разработки для бизнеса. Но как показал мой опыт иногда приходится отходить от этого правила и, даже, получать от этого пользу. Я имею ввиду не только интерес и удовольствие от разработки, но и плюшки для проекта в целом. Об одном моем подобном опыте можно прочесть несколько слов под катом.




Введение


То как сейчас мы создаем веб-приложения сильно отличается от кода, пришедшего к нам на поддержку из стародавних времен, когда по телевизору показывали Фабрику Звезд, модно было ходить с расклодушкой, а PHP только начинал приобретать признаки Объектно-ориентированного языка. Программирование в нулевые мне представляется великолепной иллюстрацией к идеям Дарвина: тогда почти любой разработчик-одиночка создавал собственные решения, некоторые из них захватывали умы более чем одного человека, и пройдя ускоренный естественный отбор, фреймворки и CMS стали титульными, образцами лучших и наиболее популярных методов разработки. В некоторых случаях, все же, только популярными, без слова «хорошее» или тем паче «лучшее».



Но в отличии от динозавров и мамонтов далеко не все альтернативные решения ушли в небытие, особенно на бекэнд, и я знаю об этом не понаслышке. Мне довелось поработать, не скажу с большим, но довольно солидным количеством legacy на php. Кое-что было просто ужасно, а некоторые сайты и даже CMS были довольно интересные. Мне нравится иногда покопаться в том, что рождалось в умах первопроходцев. Тогда не было такой стандартизации, и хотя чаще всего это превосходный материал для изучения анти-паттернов, но этот код меня забавляет, делает работу похожей на ИТ-археологию.

Возлюбленное наследие


Лично мне нравится в работе с работающими сайтами на legacy — внести правку, убрать какой-то дикий костыль, уменьшить уровень хаоса и при этом не сломать работу всей системы. Чувствую в такие моменты себя человеком, сделавшим этот мир немного лучше, и это круто.

print " <button onClick='domultimove();' class=controlbutton><img src=syspix/ico32_move.gif border=0><br>перенос</button>";
print "<b>" . $ITEM->Description . "</b>:<br>";
$browsebgcolor = "#D9D9D9";
$sql = "select i.ID, m.Name, i.perm, i.descr from item4 i inner join main m on i.ID=m.ElementID";
echo "<script language='JavaScript'> document.location='" . $_SERVER['PHP_SELF']";


Частой отличительной чертой legacy является каша из кода, написанного на разных языках, хотя и в современной разработке, конечно же, мы в PHP классы можем добавлять, например, код на SQL. Но я говорю о другом, в legacy нередко идет поток вселенской мысли разработчика — о чем и на какой языке он думал, то и писал потоком. Я хочу рассказать о подобной ситуации с одним мега-олдскульным CMS-решением, с которым работал некоторое время. Там все было настолько «чудесно», что я просто очень рад, что смог все-таки кое-что исправить и сделать так, чтобы сайт стал работать существенно корректней и быстрее.

Итак, мне в работу попал сайт крупной компании, написанный в первой половине двухтысячных. В этом проекте все базировалось на классах с одним методом, в котором происходило все: и работа с логикой, и вывод интерфейса (view) и обращения к базе, при чем, sql был прям там же между командами
print "<table>";
. Вносить правки в работающий на таком коде сайт, кстати, с неплохой посещаемостью и коммерческой составляющей, представляло из себя не самое приятное, но очень веселое мероприятие.



Нетрудно догадаться, что я сильно облегчил жизнь бекэнд-разработчиков, для начала вынеся вывод верстки в шаблоны. Для этого я использовал уже готовый и довольно популярный шаблонизатор twig. Это было несложно и быстро, так что я даже не особо и выделял время на рефакторинг. Следующим шагом по-моему мнению нужно было что-то сделать с запросами к базе данных, в конце концов, MVC не зря так популярна у нас в веб.



Насмотревшись на Симфони и Ларавел, я решил, что и здесь подход с использованием ORM отлично впишется. Поможет вынести работу с Базой Данных и оставить пока еще не-до-контроллерам только работу уже с полученными данными. Логично и совершенно правильно использовать уже существующие решения. Поэтому перво-наперво я ринулся в packagist посмотреть, какие альтернативы у меня есть кроме Docktrine, но хорошенько подумав, пришел к неутешительному выводу, что это не столь важно. Дело в том, что в этом проекте была довольно необычная структура данных. Такого я не встречал нигде более, хотя я работал с MODx :) Передо мной встала проблема: использовать популярные open-source ORM так, как я хочу не получится, ну, по крайней мере это будет то еще приключение. Так я решился на создание велосипеда.

Немного про то, что же я сделал




Да, я решил, что напишу ORM на PHP с нуля (нет, ну идеи и концепции перенятые у того же Docktrine у меня-то были) специально для этого проекта, да так, чтобы это работало со структурой данных. Ведь это рабочий сайт, и никто не был готов выделять ресурсы программистов на задачи «переписать все с нуля с нормальной структурой БД». Праотцы основавшие эту CMS создали 2 типа объектов, при чем один из них еще и делился на внутренние «типы данных»: ресурсы, у которых есть даты, ссылки, разные типы текста, изображения и еще ряд хранились в 2 таблицах, но были и объекты, хранящиеся в одной таблице, их думаю можно назвать системными данными.



Я не хотел, чтобы применяя обращения к моделям, приходилось бы думать о джоинах, или хотя бы постараться сократить такие моменты до минимума. Поэтому я решил, что модели должны быть двух типов: для одно-табличных объектов и для основных двух-табличных. Так как у этих Моделей-классов много общих методов, тот же ORDER BY или LIMIT, поэтому каждый базовый класс, на основании которого и будут создаваться конкретные Модели, я наследовал от общего Абстрактного класса.

ORM

Как можно видеть из дерева, я так же добавил поддержку разных типов Баз Данных, что в данном случае избыточно. Но я в тот момент вошел в «поток» и творил :). Также очень правильным в данном случае шагом явилось, то что я делал это на базе PDO, ибо использовавшийся в коде php-mysql не позволял переводить сайт на седьмую версию языка, а это хотелось исправить на корню, как говориться.

$element = (new Model())->getOne($id);


Благодаря тому, что я хорошенько разобрался в логике структуры Базы данных, у меня получилось сделать поиск и получение ресурса только по его ID, даже не зная каким внутренним типом данных обладает ресурс, что было обязательно при старом подходе. Настоящая объектная работа с данными, и мы забываем об sql в коде.



Заключительные абзацы...


Эта работа принесла 2 неожиданных для меня поворота. Во-первых, я попытался все написать сразу в виде кода, и ничего не получилось. Мне пришлось взять ручку, блокнот, выйти на природу и под щебет воробьев и жужжание пчел сначала нарисовать, что я хочу получить, как это будет связано, какие мне нужны классы, и как это будет вызываться в коде «контроллеров». Кстати, потом реализация отличалась от изначальных зарисовок совсем незначительно. Так что, если программист ничего не кодит, это еще не значит, что он ничего полезного не делает.

Во-вторых, я справился очень быстро, многие бизнесы не любят, когда программисты тратят время на всякие не понятные рефакторинги. Я реализовал весь проект в течении примерно недели, параллельно занимаясь поставленными задачами по внедрению новых features.

Теми плюсами, о которых я заявлял в начале статьи я отмечу: последовательность и постепенность замены уже существующего кода на работающем проекте, а значит и отсутствие необходимости выделять больше времени на переход, рефакторинг кода в рамках поступающих задач. На этом откланяюсь, благодарю за чтение.
Источник: https://habr.com/ru/post/527216/


Интересные статьи

Интересные статьи

Всем привет и всех причастных – с Днем специалиста по безопасности! По случаю провели с hh.ru небольшое исследование, о том, как трудно пришлось в этом году службам безоп...
Как-то к нам пришел один прогрессивный заказчик из города N, что в средней полосе России, и сказал: «Хотим чтобы дата-центр на 100% фрикулинге работал круглый год. М...
Много всякого сыпется в мой ящик, в том числе и от Битрикса (справедливости ради стоит отметить, что я когда-то регистрировался на их сайте). Но вот мне надоели эти письма и я решил отписатьс...
Предыстория Заканчивалось жаркое лето, позади был прекрасных семейный отдых на теплом ласковом море, и впереди уже проступали очертания серых рабочих будней. Чтобы не поддаться осенней депрессии...



В этом цикле статей мы создадим свою реализацию React с нуля. По окончании у вас будет понимание, как работает React, какие методы жизненного цикла компонента он вызывает и для чего. Статья ра...