Comments 39
Чего стоит только противоракетный маневр с местоположением моделей...
Это про перемещение моделей в папку Models?
4.2 — Models typically live in the app/models directory
5.0 — Models typically live in the app directory
8.0 — Models typically live in the app\Models directory.
Нахрена?
На размышление даётся 30 секунд.
Для меня этот фрейм умер на 4.2 а для всей команды на 5.* и за постоянных внутренних переделок фреймворка. Симфония будет лучше с цайклс вполне съедобно, если не нравится доктрина как мне.
Сам сижу на yii2 и на nodejs, это позволяет быстрей пробовать прототипы для бизнеса.
Текущий подход yii3 очень нравится, ребята двигаются в верном направлении:
1 симфони консольные команды легкие и элегантные.
2 легкие веб контролеры с di, мы используем то что нам нужно.
Насчет статьи, код отформатирован через phpcs под кодстайл фреймворка, считаю что стандартное форматирования phpcs2 лучшие, так как соответствует пхпшторму.
Спасибо за статью и опыт.
// you can fetch the EntityManager via $this->getDoctrine()
// or you can add an argument to the action: createProduct(EntityManagerInterface $entityManager)
$entityManager = $this->getDoctrine()->getManager();
$product = new Product();
$product->setName('Keyboard');
$product->setPrice(1999);
$product->setDescription('Ergonomic and stylish!');
// tell Doctrine you want to (eventually) save the Product (no queries yet)
$entityManager->persist($product);
// actually executes the queries (i.e. the INSERT query)
$entityManager->flush();
А что не так с этим способом? Мы на C# так же делаем...
Если придерживаться мнения, что разработка — должна происходить быстро и доставлять удовольствие программисту, то тут — перебор. Программист целых 3 строки будет миллион раз повторять в коде, чтобы сохранить запись. Не говоря уже о читаемости — «persist» переводится как «сохранить», но оно не сохраняет. «flush» переводится как «сбросить», «очистить», но оно сохраняет в базу.
Но это, конечно, holy war. Кому-то нравится программировать, кому-то нравится смотреть на абстракции в коде.
Ну, наименования тут взяты прямиком из Java Persistence Api (JPA), лично мне они тоже кажутся несколько неудачными — я-то привык к Add и SaveChanges :-)
Что же до числа строчек — то тут всё просто. От первой строчки вы не избавитесь никак, соединение с БД по-любому нужно или получить, или создать. А разделение persist/flush нужно чтобы была возможность сохранять в БД несколько сущностей за раз.
Судя по этому комментарию — вы не работали с доктриной, иначе бы не писали подобного. Ёлка удобнее доктрины только для чтения и только для относительно простых вещей. А работа с ней на запись — это сущий ад, особенно, когда дело касается нормальной транзакционности и отношений.
Вы же понимаете, что в доктрине в идеальном случае достаточно вызывать один раз persist($object)
для просчёта отношений + flush()
для сохранения состояния и всё сохранится в БД:
1) В одной транзакции (если включено)
2) Исключая дубликаты
3) В нужном порядке
4) Только те данные, что реально изменились
5) Включая все отношения этого объекта, которые были изменены (даже какие-нибудь many2many).
$user = new User();
// В eloquent пришлось бы тут делать save, что б появился PK у модели.
$user->comments = $user->comments->filter(fn ($c) => $c->id === 42);
// eloquent: $user->comments()->detach($user->comments()->first(42));
$user->comments[] = new Comment();
// eloquent: $user->comments()->attach(new Comment());
$user->friends[] = new User();
// eloquent: $user->friends()->associate(new User());
/// ... etc
$em->persist($user);
$em->flush();
// eloquent: $user->save()
В eloquent подобные операции — смерти подобны. А потом это ещё заворачивать в транзакцию…
я пишу код, чтобы делать жизнь юзеров лучше, а не чтобы наслаждаться идеальностью абстракций в своем кодеА паттерны (включая тот же UoW, IM) от сырости или оттого, что коту нечего делать, завелись, видимо?
ORM это всегда оверхэд по производительности, по коду и по логике. То что на SQL делается за 1 логическую операцию, на ORM обрастает абстракцией, которую очень тяжело контролировать. Сегодня борол Laravel: нормализовали клиентов, появился detail к клиентам с аккаунтами. В одном из режимов надо показывать всех клиентов, кроме тех, которые есть только в одном определенном аккаунте. Клиентов пара миллионов. Laravel для педжинейшена делает 2 запроса к БД: один на COUNT(*), один уже на данные с ORDER BY и LIMIT. Оптимизируя один из запросов, второй начинает недопустимо проседать. В ход шли самые современные методы MySQL: WITH, хинты. В общем, на ровном месте, борьба с ветряными абстракциями на несколько часов, которая разрешилась только практически pure sql
$product = new Product();
$entityPersister->save($product);
Ну я знаю как минимум 3 случая ещё, когда feature PR отклонялся, а потом дядя Ти выкатывал какой-то лютый **** со словами "смотрите, какую я фичу запилил". Так что ничего удивительного. Вы не первый — вы не последний.
В нашем проекте есть json поля в базе, и много бизнес логики для них, соответственно обращение к таким атрибутам очень частое, и вот при каждом обращении под капотом вызывается json_decode/json_encode. Я был разочарован когда раскопал откуда тормоза пошли.
Второй пример это функция Arr::get(), а точнее ее использование. Она позволяет получить значение из вложенного массива передавая путь вида «path.to.value», и соответственно реализация содержит explode() и цикл по сегментам пути. Так вот очень важная функция config() под капотом вызывает ту самую Arr::get() при каждом обращении, никак не кэшируя результат. И если у вас где-то в большом цикле вызов config() — прощай производительность. Эта Arr::get() используется и некоторых в других местах аналогичным способом.
Это два ярких примера которые пришли в голову сразу, на самом деле там еще найдется. Вполне возможно что в вашем проекте это не актуально, но эти примеры отлично иллюстрируют подход разработчиков к вопросам производительности.
и у него получается. Пипл хавает.
Пиплов так много набралось, что совместными усилиями все таки смогли сделать приличный феймворк, хоть и с достаточным количеством оверинженеринга
В целом было бы чхать на это, если бы он на некоторые больные места не накладывал свое вето, как например composite primary keys.
Как я пытался улучшить Laravel, а сделал только хуже