Здравствуйте,
представляю вашему вниманию BlackFox.
У вас никогда не возникало ощущение того что PHP-фреймворки (далее - движки) написаны как-то странно, коряво, шизофренично (несколькими не согласными друг с другом людьми) и что они чаще мешают своими стандартами, чем помогают функционалом? Я повидал многие из них, живу с этим ощущением вот уже больше семи лет и пилю свой движок потихоньку.
---
Вот например для работы с базой данных в Laravel используется Eloquent ORM (паттерн Active Table) с конструктором запросов. Конструктор запросов является ни чем иным как полной копией языка запросов SQL, реализованным в виде обертки на PHP. Да, он позволяет "легко и быстро" мигрировать с одной базы данных на другую, но как часто вы это делаете? А для того чтобы добавить колонку в таблицу, необходимо создать миграцию. Для того чтобы удалить - миграция. Для того чтобы переименовать или изменить - снова миграция. И все эти миграции необходимо держать в уме при релизах.
BlackFox использует иной подход. Отнаследовав от класса SCRUD вы создаете свою таблицу, описывая ее поля в виде структурного массива. Когда требуется добавить\изменить\удалить — просто запускается метод Synchronize(), который ищет разницу между вашим описанием и реальными колонками в базе данных и эту разницу нивелирует. А метод поиска информации Search() так вообще конфетка, он принимает на вход массив фильтров, переданных напрямую из формы, сам автоматически эскейпает все принимаемые данные, да еще и выдает отэскейпанные данные на выходе, чтобы ваша голова не болела при составлении очередного отображения.
---
Или вот например в Yii контролеры и отображения разнесены по разным директориям, как будто некоторые отображения могут быть использованы более чем одним контроллером. А действие контроллера вынужденно возвращать готовый отрендеренный html, что не позволяет элегантно переиспользовать его там где нужен точно такой же ответ, но в формате json, xml или ajax.
BlackFox использует иной подход. Контроллеры и отображения объединены в единую структуру, которой управляет класс-наследник от Unit. Все публичные методы этого класса являются действиями и возвращают массив данных, подключаемых к отображению. А пользователю предоставляется возможность самому решать в каком формате он хочет получить ответ. Но самое вкусное тут это возможность наследования контроллеров вместе с отображением: если у отнаследованного контроллера отсутствует отображение, то будет подключено отображение родителя (или родителя родителя...).
---
Реализация роутинга во многих движках лично у меня вызывает культурный шок. Если все роуты для сайта описываются в одном файле, то становится невозможно вести разные разделы сайта в разных репозиториях, плюс возникает дополнительная нагрузка (обработка неиспользуемых правил роутинга).
В BlackFox вы регистрируете в конфигурации все папки, являющиеся виртуальными корнями, а затем создаете в них привычную структуру из папок и файлов, как в старом добром нативном PHP. А если возникает потребность в ловле запросов на несуществующие файлы\папки, то создаете в соответствующем разделе файл .router.php, на который такие запросы перенаправляются движком. В файле .router.php можно описать роутинг любой сложности.
---
Движок полностью готов к разработке реально сложных проектов, на текущий момент на нем уже создано несколько реально работающих боевых некоммерческих проектов. Однако документация все еще сырая, поэтому я был бы крайне признателен тем первым людям, кто бы ее посмотрел и дал мне фидбек на темы: что и где не понятно, чего не хватает.
Благодарю за внимание =)
представляю вашему вниманию BlackFox.
У вас никогда не возникало ощущение того что PHP-фреймворки (далее - движки) написаны как-то странно, коряво, шизофренично (несколькими не согласными друг с другом людьми) и что они чаще мешают своими стандартами, чем помогают функционалом? Я повидал многие из них, живу с этим ощущением вот уже больше семи лет и пилю свой движок потихоньку.
---
Вот например для работы с базой данных в Laravel используется Eloquent ORM (паттерн Active Table) с конструктором запросов. Конструктор запросов является ни чем иным как полной копией языка запросов SQL, реализованным в виде обертки на PHP. Да, он позволяет "легко и быстро" мигрировать с одной базы данных на другую, но как часто вы это делаете? А для того чтобы добавить колонку в таблицу, необходимо создать миграцию. Для того чтобы удалить - миграция. Для того чтобы переименовать или изменить - снова миграция. И все эти миграции необходимо держать в уме при релизах.
BlackFox использует иной подход. Отнаследовав от класса SCRUD вы создаете свою таблицу, описывая ее поля в виде структурного массива. Когда требуется добавить\изменить\удалить — просто запускается метод Synchronize(), который ищет разницу между вашим описанием и реальными колонками в базе данных и эту разницу нивелирует. А метод поиска информации Search() так вообще конфетка, он принимает на вход массив фильтров, переданных напрямую из формы, сам автоматически эскейпает все принимаемые данные, да еще и выдает отэскейпанные данные на выходе, чтобы ваша голова не болела при составлении очередного отображения.
---
Или вот например в Yii контролеры и отображения разнесены по разным директориям, как будто некоторые отображения могут быть использованы более чем одним контроллером. А действие контроллера вынужденно возвращать готовый отрендеренный html, что не позволяет элегантно переиспользовать его там где нужен точно такой же ответ, но в формате json, xml или ajax.
BlackFox использует иной подход. Контроллеры и отображения объединены в единую структуру, которой управляет класс-наследник от Unit. Все публичные методы этого класса являются действиями и возвращают массив данных, подключаемых к отображению. А пользователю предоставляется возможность самому решать в каком формате он хочет получить ответ. Но самое вкусное тут это возможность наследования контроллеров вместе с отображением: если у отнаследованного контроллера отсутствует отображение, то будет подключено отображение родителя (или родителя родителя...).
---
Реализация роутинга во многих движках лично у меня вызывает культурный шок. Если все роуты для сайта описываются в одном файле, то становится невозможно вести разные разделы сайта в разных репозиториях, плюс возникает дополнительная нагрузка (обработка неиспользуемых правил роутинга).
В BlackFox вы регистрируете в конфигурации все папки, являющиеся виртуальными корнями, а затем создаете в них привычную структуру из папок и файлов, как в старом добром нативном PHP. А если возникает потребность в ловле запросов на несуществующие файлы\папки, то создаете в соответствующем разделе файл .router.php, на который такие запросы перенаправляются движком. В файле .router.php можно описать роутинг любой сложности.
---
Движок полностью готов к разработке реально сложных проектов, на текущий момент на нем уже создано несколько реально работающих боевых некоммерческих проектов. Однако документация все еще сырая, поэтому я был бы крайне признателен тем первым людям, кто бы ее посмотрел и дал мне фидбек на темы: что и где не понятно, чего не хватает.
Благодарю за внимание =)
We’re gonna build a framework,
‘cos we wanna use one, but don’t wanna choose one,
We’re gonna build a framework,
We didn’t like the others, so we’ll write another
А некоторыми даже зарабатываю себе на хлеб прямо сейчас
Wild Card, навалили в кучу и фреймворки и библиотечки и названия для паттернов... и самой идеей песни обесценили работу настоящих и будущих исследователей в области PHP-программирования... впрочем чего еще ожидать от артистов.
Новый php-фреймворк? Серьёзно?
Насколько я понял, там как раз группа из разработчиков собралась. У них хобби такое, песни о программировании. Ну намешали, конечно, из разных языков всякого для рифмы
Вот, кстати, твиттер автора: twitter.com/dylanbeattie
CTO @SkillsMatter. Developer, keynote speaker, guitar player, Microsoft MVP. Creator of @RockstarLang. Organiser of @LondonDotNet.
Чем SCRUD отличается от Doctrine?
Команда `doctrine:migrations:diff` делает то же самое – сама находит разницу и создаёт миграцию.
Команда `doctrine:schema:update` те же яйца, но для лентяев – никаких миграций, сама находит разницу и просто применяет изменения к хранилищу.
Проблему переезда между хранилищами решает DAO, а не ORM – и это разные вещи, внезапно.
Unit и контроллеры – в чём отличие от Symfony normalizer/serializer/encoder? Из контроллера можно вернуть массив/модель/число/строку – оно будет правильно нормализировано во что угодно, а ответ возвращён в любом виде, который захочет клиент. И всё это автоматически.
Роутинг. В Symfony есть аннотации – все описанные проблемы решаются описанием роуат прямо в методе-обработчике. Для особо упоротых, у кого куча типовых CRUD'ов без сложной логики, роуты можно замапить прямо на модели через api-platform.
И ещё кое-что про роутинг. Нужно проводить замеры, конечно, но есть подозрение, что ваше решение будет адски тормозить – операции с ФС долгие. При этом, например, роутер из аннотаций симфонии один раз компилится, складывается в опкэш и имеет минимальный оверхэд.
В целом, как проект для обучения или как результат эволюции из кода "всё в одном" – хорошо. Даже для продакта сойдёт, если им занимается всего один человек. Но брать в команду, в проект со сложной логикой, в хайлоад – точно нет, есть инструменты на порядок лучше. Целевая аудитория не понятна тоже.
В целом странная аргументация: взяли всего два фреймворка (и при том не самых популярных/удобных), придумали проблемы и героически их решили не самым эффективным образом.
Хотя стремление и развитие полезное, конечно.
То что доктрин умеет создавать мигрирацию это очень клёво.
SCRUD пошел дальше, он сам молча мигрирует, вам даже думать об этом не нужно)))
SCRUD это Active Table, где ваша таблица это прямой наследник, уже обладающий всеми методами-операциями. Некоторые ваши операции (Update, Select) сразу описываются относительно пачек элементов, а не единственного элемента (как в Active Record), что позволяет в выбирающий метод передавать фильтр (в виде php-массива) напрямую от пользователя без проверок и ограничений, на мой взгляд намного удобнее+быстрее+меньше кода. Можно просто на глаз сравнить объем документации, чтобы уловить что они как бы в разных весовых категориях.
— — —
Принципиальных отличий между юнитом и контроллером Симфони практически нет. Кроме одного: финальное действие контроллера в Симфони обязано вернуть html (return $this->render(...)), а в юните действие возвращает чистые данные (return $RESULT), которые в дальнейшем подключаются самим юнитом к соответствующему отображению. Это позволяет ре-использовать это действие из других действий, при необходимости. Кроме того юнит позволяет действиям самим диктовать наверх те параметры, которые им нужны, а сверху вы определяете лишь порядок запуска действий (без параметров), юнит сам подставляет эти параметры из запроса пользователя (при желании можно дополнить запрос пользователя своими данными или запускать действия напрямую по старинке).
— — —
Я проведу замеры роутинга, а пока вот мои соображения:
- в других "современных" фреймворках роут вычисляется на основе какой-то структуры, загруженной в кеш
- в блекфоксе подключаются два файла: сперва движок, затем запрошенный php-файл (если он есть) или рядом лежащий .router.php; практически старый-добрый php, оптимизация которого ложится на оптимизатор
— — —
В хайлоад я бы вообще не брал PHP, я бы брал по нарастающей: Node.js, C++, C, Assembler.
Для хайлода еще интересно посмотреть Swoole.
Что касается Блекфокса, это фреймворк для средней нагрузки, но экстремально сложной бизнес-логики, такой как, например, кастомные CRM. Шикарно скалируется на команду (проверено).
— — —
странная аргументация: взяли всего два фреймворка (и при том не самых популярных/удобных), придумали проблемы и героически их решили не самым эффективным образом
ну проблем то на самом деле намного больше чем две, я просто вынес две самые острые для привлечения внимания только и всего
если у вас нет никаких проблем с доктриной и симфонией — я за вас очень рад, а блекфокс вам не нужен
блекфокс для тех у кого проблемы с текущими "топовыми" движками и не отсохло чувство интереса
Я тоже — пока ещё — зарабатываю, используя бэк-энд на php. Но время php в целом и php-фреймворков в частности стремительно уходит. Значительная часть архитектуры (или, если угодно, сложности) веб-приложения перемещается на фронт, а будущее того, что останется на бэк-энде лежит где-то рядом с Go и Node.js
Нет, Doctrine = DataMapper. При желании, она превращается в ActiveRecord с помощью ObjectManagerAware, но обычно в этом нет смысла.
> заниматься сексом с его синтаксисом
А есть пример?
> словно мне может понадобится объект бизнес-логики без сохранения в бд
Да, может. Если лично у вас не было таких задач – не значит что оно не нужно. Для простеньких CRUD'ов и AR хватит, конечно.
Данные могут храниться не только в mysql, но и в другого типа БД, в файлах, по сети, в контейнерах, в моделях легаси-кода на другом фреймворке. А ещё ваша стройная и цельная доменная модель может быть агрегатом из нескольких источников. Ещё бывает так что чтение – из двух источников, а запись – вообще в третий. Примеров много.
Как там у вас с CQRS, кстати?
> SCRUD пошел дальше, он сам молча мигрирует, вам даже думать об этом не нужно
Ну да, а потом на проде срочно приходится патчить базу вручную (в лучшем случае)? Например, если эта молчаливая миграция не поняла что какой-нибудь enum был переименован, изменилась валидация или появились новые связи на существующих данных.
> финальное действие контроллера в Симфони обязано вернуть html (return $this->render(...))
Нет. Можно возвращать из контроллеров сразу любые данные, автоматически конвертируемые во что угодно (json/xml/yaml/csv), например, на выбор клиента/конфига. Вплоть до автоматического однострочника в простых экшенах: `return $this->userRepo->findBy($request->attributes);`
> А метод поиска информации Search()
У всех указанных фреймворков есть эта фича. У Доктрины, например: `ObjectRepository::findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)`
> В хайлоад я бы вообще не брал PHP
Здесь пишу не про хайлоад ибо если у вас в проекте самое узкое место роутер, а не диск/сеть – пора менять язык (-: Кстати, на правах оффтопа, есть положительный опыт хайлоад-проектов на Phalcon.
Здесь скорее делаю акцент на том, что самые эффективные роутеры это SwitchRoute/FastRoute/SymfonyRoute – зачем писать свой велосипед, если практически всегда они будут быстрее любого хранилища и/или сети? Но тут нужны бенчмарки, конечно, вдруг ваш быстрее – я выразил сомнение в этом, зная как внутри работают представленные конкуренты, но не вникал в ваш код.
> блекфокс для тех у кого проблемы с текущими "топовыми" движками
Пока что из представленных проблем я пока увидел только одну – автор не справился со входом в другие фреймворки или в документацию к ним. Например, многие примеры из других фреймворков не соответствуют реальности. Или же у автор просто не сталкивался с проектами на сложной логике или с проектами где поддержка длится годами.
> Значительная часть архитектуры (или, если угодно, сложности) веб-приложения перемещается на фронт
Не "перемещается", а "увеличивается". Фронт становится сложнее, но бэк и его сложность никуда не делись. PHP развивается, код и культура уже не хуже чем у C#/Java, но хренокодеры всё ещё существуют, конечно, в больших количествах.
>> А есть пример?
Да вон в оф доке доктрины все примеры: чтобы выбрать постранично все сообщения со всеми спасибками ко всем сообщениям (много к одному) мне нужно там попотеть, создав отдельный QueryBuilder + Criteria. В блекфокс скруде я просто говорю:
где:
USER - это поле-ссылка на юзера (многие к одному)
LIKES - это виртуальное поле от лайков к сообщениям (один ко многим)
и вуаля, он делает два запроса, в одном выбирает сообщеньки с пользователями (через лефт-джойн), во втором он выбирает все лайки, ссылающиеся на все выбранные сообщения и матчит их между собой. Простота и гармония и отсутствие необходимости тратить время, внимание и ресурсы на мапперы, поскольку я разрабатываю веб-приложение, которое с вероятностью 99.9% требует как минимум чтения данных из БД.
А там где не требует, там конечно да, можно без SCRUD да и без доктрины обойтись. Класс User, например, как раз такой пример, он не наследник от SCRUD, читает данные из сессии, а когда загружает из БД, дергает другой класс Users.
>> Да, может. Если лично у вас не было таких задач – не значит что оно не нужно.
Вообще то если у меня не было таких задач -- это именно то и значит, что оно не нужно. Или нужно так редко, что имеет смысл не думать об этом. Что я и делаю, тем самым экономя собственную оперативную память.
Мой любимый холивар на эту тему это третья нормальная форма против шестой. Вы какую форму предпочитаете?
>> Как там у вас с CQRS, кстати?
Ну метод Create пожимает плечами и говорит что будет возвращать айдишник не смотря ни на какие внешние по отношению к движку стандарты
>> Ну да, а потом на проде срочно приходится патчить базу вручную
А у меня все хорошо работает
>> Нет. Можно возвращать из контроллеров сразу любые данные
Ну ладно, контроллер Симфонии хороший. Наверно. Я не знаю, ни разу не работал с ним. Я просто посмотрел его документацию и сделал такие вот выводы. Вам, конечно, виднее.
>> автор не справился со входом в другие фреймворки или в документацию к ним
Отчасти это правда. Мне, как конечному существу, довольно сложно войти во все фреймворки сразу. Я вошел только в очень ограниченное их число
Чтобы толком войти во фреймворк необходимы реальные задачи на нем, а не документация или курс на юдеми.
Обратная сторона этой правды может заключаться в том что фреймворки, в которые я "не смог" войти через документацию — так себе фреймворки.
В конечном счете BlackFox может оказаться просто в пустую потраченными годами моей жизни, а может оказаться бриллиантом, распространяющимся экспонентно и в ближайшем будущем захватившем весь "рынок". Вам никогда этого не узнать, если не попробуете
Они ещё долго на php будут. И классическая связка LAMP ещё некоторое время будет актуальна. Но...
Динозавры, вон, владели Землёй миллионы лет, и ещё долго цеплялись за жизнь после метеорита — но их судьба была решена уже в день его падения.
а будущее того, что останется на бэк-энде лежит где-то рядом с Go и Node.js
Будущее ещё никому не известно, это разговор ни о чём. Кто строил предположения хотя бы лет на 5 вперёд, пока мало в чём угадал. Технологии меняются очень быстро, но пока ни один из обсуждаемых языков не умер. Про то, что javasсript так выстрелит тоже не очень-то думали, создавался он для довольно скромных целей изначально.
Вообще не знаю примеров проектов, которые мигрировали бы с php или python на node.js. Вы знаете такие? Буду удивлён, если да. На go, как правило, переносятся только отдельные части, но полностью проект не переписывается. На проде go используется пока достаточно редко, у языка своя специфика, разработчиков на нём пока немного, желающих писать на нём проекты с нуля тоже что-то не очень много. Свою нишу он уже, безусловно, займёт, но чтоб он всерьёз потеснил привычный бекенд - такого не наблюдается, не знаю, откуда у вас это ощущение, вы где-то это наблюдали или это умозрительное предположение? На конференциях тоже об этом не видел докладов, статей таких не читал, хотя за разными ресурсами, нашими и иностранными, активно слежу.
У nodejs же, на мой взгляд, куда больше проблем и это менее стабильный стек, чем php. У нас были проекты полностью на nodejs, девопсы много ругались и трахались с деплоями и настройкой, море было баг, проблем, всё это ужасно долго компилируется, не понимаю, отчего у вас такой восторг.
Сейчас весь enterprise стабильно пишется на Java, обычный веб пишут на php и python, с вкраплениями из других языков, где это нужно. По регионам сильно преобладает php и cms-ки, много yii и laravel, есть symfony.
В php начали работать над yii3, многие его очень ждут: github.com/yiisoft/yii2/releases/tag/3.0.0-alph...
yiiframework.ru/forum/viewtopic.php?t=47759#p23...
В php много всего происходит-то, посмотрите хотя бы в сторону reactphp.org/. Идёт движение в сторону асинхронности. В php будущей версии можно будет использовать напрямую код из c и других языков. Это где видно, чтоб умирающий был настолько активен?
Но в среднем по больнице разницы на чём писать нет, если вы хорошо знаете тот стек, с которым работаете. Личные проекты можете писать хоть на go прямо сейчас и не ждать, пока "динозавры вымрут", это случится не скоро. У "чистых" фронтендеров в основном наблюдаю стремление тащить на фронт всё, что можно и не нужно, и решать там такие задачи, которые там решаться не должны ни в коем случае. Видишь это и хватаешься за голову. В целом согласен, что клиент утолщается и становится сильно сложнее, выделяются специализации внутри фронтенда, но есть пределы этому утолщению, есть задачи, которые по-прежнему решаются только на беке.
Само по себе написание собственного фреймворка для автора и небольшой команды - это неплохо, много нового узнаёшь, хорошая задача, чтобы прокачаться. Но так вот для широкой публики смысла особо нет, потому что есть много уже существующих вариантов и возможность брать отдельные компоненты и их сочетать. Да, и будет yii 3, посмотрим, что он нам принесёт.