Через несколько месяцев общественности будет представлен гибрид PHP-фреймворка и CMS. По заявлениям разработчиков, фреймворк возьмёт лучшее из философии Symfony и часть её открытых компонентов, при этом устранит недостатки и сложности, с которыми новички сталкиваются при использовании данного фреймворка. Также система позволит создавать простые блоги и магазины в технике zero code, то есть не открывая исходный код и не нанимая разработчиков.
Здесь нужно сделать небольшую паузу, и отметить, что пока единственный разработчик данного проекта — это я. И совсем не факт, что на выходе получится что-то удобное или даже просто вменяемое. Тем не менее, данный челлендж показался мне интересным, и поэтому — почему нет 🙂
То есть заголовок статьи — отчасти шутка, отчасти декларируемая цель, но не стоит воспринимать его всерьёз.
Вообще историю надо начать с того, что я за последние полгода 3-4 раза помогал знакомому с проектами на WordPress. Сам я с 2019 года работаю с Symfony, и в общем и целом застал все версии начиная с 2.x, но особенно долго работал с версией 5. Да, сейчас уже вышла седьмая, но основные концепции не сильно изменились.
И работая с сайтами на WordPress, я буквально успел поседеть от стресса. Вот что меня раздражало больше всего:
-
Неочевидная система срабатывания хуков. Как понять, в какой очерёдности они будут обработаны?
-
Сам WordPress во многом сделан в функциональном стиле. Я раньше в юности сам был адептом такого подхода, но он крайне плохо подходит для больших и сложных систем
-
Почему-то многие сайты тормозят просто кошмарно, при этом число плагинов в целом выглядит в рамках разумного
-
Сложности при отладке в PHPStorm (иногда точки остановки не срабатывают, впрочем, тут скорее всего виноваты мои кривые руки — однако на Symfony таких сложностей ещё никогда не было). Причём порой эти сложности фатальны: включим отладку через расширение браузера и откроем главную страницу админки — и вот мы получаем бесконечное зависание загрузки, приходится отключать отладку и повторять всё по новой, а то и делать рестарт вебсервера.
-
Безобразная система хранения данных. Серьёзно, хранить почти всё в таблицах posts и posts_meta — гениальное решение, вот только для разработчика искать что-либо становится целым квестом, а сами таблицы по вертикали разрастаются до просто чудовищных размеров. Кроме того, данные от разных плагинов сильно фрагментированы, в итоге если получить список, условно, всех способов оплаты для платёжного шлюза — id будут отличаться на огромные величины, если эти способы добавлялись не в один заход, а в течение, например, года. Кроме того, иногда из-за повисших запросов или багов в сторонних плагинах возникают «осиротевшие» строки, которые практически невозможно удалить программным способом, написав сценарий. Сам WordPress тоже такие чистки делать, вроде как, не умеет.
-
Сложная процедура добавления кастомных полей — для этого есть ряд плагинов, но в БД это хранится всё так же ужасно, и если всё-таки придётся писать код (а это в 90% случаев так), то придётся писать его с учётом того, какой плагин использовался, т.к. подходы там везде немного отличаются.
-
Не очевидное для новичков понятие таксономий — сущностей, которые существуют только лишь в коде, но не в БД
-
Необходимость написать достаточное количество не самого очевидного кода чтобы реализовать AJAX подгрузку элементов в каталоге. Придётся по новой реализовывать сортировку и фильтры, а также убедиться, что сортировка точно совпадает с сортировкой первой страницы, если она грузится не через AJAX.
-
Из коробки нет никакой ORM, при написании плагинов приходится тащить или писать свою.
-
Онлайн обновление плагинов в административной панели почему-то часто происходит неоправданно долго.
Теперь о том, какие сложности (болевые точки) возникали у меня при работе с Symfony:
-
На достаточно больших проектах крайне долго очищается кэш (40-90 секунд). Очистка его просто необходима, если мы находимся в prod окружении и отредактировали шаблон. dev окружение на проектах такого размера тоже изрядно тормозит, причём речь не идёт про ноутбуки с условными Core 2 Duo или железом ещё хуже, тормоза были на топовом iMac 2019 года кастомной конфигурации с 32 Гб RAM и Core i7 9700H на борту.
-
Из-за бага в xdebug, который разработчики соизволили исправить только в апреле 2024 года, при отладке любой, даже самый мощный процессор постоянно уходил в 100% нагрузку по одному ядру, что приводило на слабых системах к тормозам, а на системах с недостаточным охлаждением вроде ноутбуков и iMac — к ужасному шуму. Причём этот момент не проявлялся на простых страничках, сделанных без фреймворка.
-
При плохо спроектированной архитектуре Doctrine работает с БД недостаточно быстро.
Например, на моей предпоследней работе на главной странице кабинета клиенту выводилась финансовая сводка по всем его проектам. Код вычислял достаточно простые формулы, но применял эти формулы к большому числу строк. Для крупных клиентов это число легко доходило до 1 миллиона или даже переваливало за него. Как итог — дашборд прогружался 60 секунд, затем PHP завершал скрипт по лимиту времени, но что ещё хуже, 3-4 таких запроса параллельно выжирали всю RAM и сервер банально падал для всех.
У владельцев бизнеса были варианты решения:
-
Докупить оперативной памяти. Этого делать не стали, т.к. дорого и не особо помогло бы.
-
Реализовать кэширование на уровне отдельных бизнес-сущностей (одна сущность имеет примерно 10-500 строк/позиций, всё зависит от клиента и его потребностей) или даже ещё мельче — на уровне групп позиций внутри сущности (что они и сделали через Redis, но потом отключили его, потому что он моментально выжирал всю память и всё точно так же падало).
-
Реализовать просчёт агрегированных формул на чистом SQL — длинно, громоздко, тяжело поддерживать… Но внезапно при тесте, когда я ради эксперимента это сделал, оказалось, что даже для крупных клдиентов статистика считается за 0.2-0.5 секунды (правда, я успел перенести только 3 расчётных формулы из нужных 6 или 8, остальное делать не стал, потому что начальство сказало, что через SQL оно делать точно не будет, т.к. не доверяет корректности результатов, а это финансы, поэтому риски слишком велики).
-
Кэшировать как-то ещё и писать свой велосипед — решили, что долго, дорого и результат ненадёжен. В итоге команду распустили до того, как кто-либо даже попытался сделать такое решение.
Вывод такой: сами расчёты тривиальны, и тормоза явно не из-за них, а во-первых из-за IO (передача большого объёма данных между СУБД и PHP), а во-вторых из-за того, как именно Doctrine работает с сущностями в памяти (для крупных клиентов страница дашборда кабинета очень часто падала по памяти ещё до того, как истекал лимит времени, при этому лимит стоял то ли 2, то ли 3, то ли 4 гигабайта). Если же посчитать вес «чистых данных» позиций, как если бы они хранились в CSV, там явно минимум на 2 порядка меньше.
Это ещё раз подводит к мысли о том, что Doctrine в таких юзкейсах не просто неэффективна, но даже опасна.
-
У меня были сложности с открытием доступа к отдельным URL внутри пути. Например, на сайте есть веб-версия и API для мобильных приложений, доступное по пути
/api
. Так вот, открыть доступ без OAuth токена к отдельному пути внутри/api
у меня не получилось, хотя я потратил на это несколько часов и перерыл весь гугл. А при попытке перенести авторизацию пользователей на новый механизм в соответствии с рекомендациями версий Symfony 5.3 и 5.4 — я вообще пару раз получал ситуацию, когда либо всё доступно без кук вообще, то есть весь сайт открыт, либо наоборот, ничего не доступно, включая главную страницу для гостей и непосредственно форму входа. Но возможно, это опять же мои кривые руки, и стоило обратиться к конфигу Symfony актуальной версии, скачанной с сайта в чистом виде, чтобы посмотреть, как сделано там.
При разработке своей системы я учёл все эти нюансы и стараюсь сделать так, чтобы никто о них больше не спотыкался, включая неопытных новичков.
Система будет уметь:
-
Поддержку минимум двух движков шаблонов — собственного и Twig. Шаблоны кэшируются после компиляции и остаются в кэше либо до истечения времени жизни, указанного администратором в конфиге, либо до первого изменения исходного шаблона (движок сравнивает время модификации файлов)
-
Встроенную облегчённую ORM, любезно предоставленную мне товарищем
-
Три метода авторизации прямо из коробки: Сookie ssid, OAuth2 token, JWT token. Любой из методов можно полностью отключить в PHP конфиге или в админке, и также интуитивно можно менять порядок обработки путём перетаскивания блоков опций
-
Встроенные Entity и простые сервисы для 4 юзкейсов: блог, интернет-магазин, форум и служба технической поддержки. При этом пользователь сможет легко редактировать код встроенных Entity и сервисов, наследоваться от них и добавлять полностью свои. ORM будет доработана так, что автоматически подхватит все вновь добавленные Entity-классы и создаст для них таблицы в БД, а также отследит по специальной команде изменения наборов полей в уже существующих классах и обновит структуру таблиц, добавив или удалив столбцы.
Для некоторых типов проектов данное решение подойдёт плохо или не подойдёт совсем (например, сайт условного небольшого музея, который продаёт билеты в этот музей, то есть в каталоге есть всего один товар, но правила расчёта цен могут быть достаточно нетривиальны). В этих случаях WordPress вместе с написанием собственного кода (если аккуратно реализовать хранение заказов и скидок в отдельных таблицах), возможно, сможет проще решить задачу.
-
Редактор всех элементов внутри админ панели
-
Три роли (Администратор, Редактор и Пользователь), а также детальные ACL правила, определяющие, что может делать каждый из пользователь, а что не может, при этом главный администратор сможет максимально точно настраивать права на уровне категорий объектов, отдельных объектов и действий над ними для каждого отдельного юзера
Что использовано из сторонних компонентов:
-
Symfony HTTP Foundation — без него никуда
-
Twig будет добавлен на более поздней стадии
-
Monolog для ведения привычных логов и для возможностей более тонкой настройки логирования
-
Firebase PHP-JWT для генерации и верификации JWT токенов
-
PHPMailer для отправки почты
Что я тащить не стал:
-
Doctrine, поскольку для простых проектов это оверкилл, и в связи с потенциальными проблемами с быстродействием, описанными выше
-
Dependency Injection и Autoworing не стал тащить или делать самостоятельно ровно по той же причине
-
Symfony Cache, поскольку пока не пригодился, а если что, пользователь сможет добавить его сам
-
Symfony Security, поскольку сам реализую упрощённый аналог
На сегодняшний день работает всё, что не связано с CMS (просмотром и редактированием бизнес сущностей). Нет никаких шаблонов для фронта, нет никакой админки.
Но это та основа, на которой дальше можно работать и наращивать функционал. Хочу услышать ваши мнения и предложения.
ссылка на оригинал статьи https://habr.com/ru/articles/867144/
Добавить комментарий