Ответ
В Symfony-проектах основным инструментом был DoctrineFixturesBundle в комбинации с Faker для генерации правдоподобных данных. Это позволяло быстро наполнять базу для разработки, тестирования и демо-стендов.
Базовый пример фикстуры для сущности Product:
// src/DataFixtures/ProductFixtures.php
namespace AppDataFixtures;
use AppEntityProduct;
use DoctrineBundleFixturesBundleFixture;
use DoctrinePersistenceObjectManager;
use FakerFactory;
class ProductFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
$faker = Factory::create('ru_RU');
for ($i = 0; $i < 50; $i++) {
$product = new Product();
$product->setName($faker->words(3, true));
$product->setDescription($faker->paragraph());
$product->setPrice($faker->randomNumber(5, false));
$product->setCreatedAt($faker->dateTimeThisYear);
$manager->persist($product);
// Сохраняем ссылку для использования в других фикстурах
$this->addReference('product_' . $i, $product);
}
$manager->flush();
}
}
Для сложных связей использовали:
- Ссылки (References): Чтобы связать, например, заказ (
Order) с существующим пользователем (User) из другой фикстуры.// В OrderFixtures $user = $this->getReference('user_admin'); $order->setCustomer($user); - Зависимые фикстуры: Группировка и порядок загрузки через
dependenciesв аннотацииORMFixture. - Пургатор (Purger): Для очистки базы с отключением foreign key checks (
--purge-with-truncate) перед загрузкой новых данных.
В некоторых проектах также пробовали AliceBundle для описания фикстур в YAML-файлах, что было удобно для команд, где не все разработчики хотели писать PHP-код для генерации данных.
Ответ 18+ 🔞
Блин, смотри, раньше в Symfony-проектах у нас был один проверенный способ набить базу тестовыми данными — это DoctrineFixturesBundle в связке с Faker. Ну, чтобы не придумывать названия товаров вроде «asdf123», а генерировать что-то похожее на правду. Для разработки, тестов или чтобы заказчику демку показать — самое то, ёпта.
Вот простейший пример, как мы обычно делали для какой-нибудь сущности Product:
// src/DataFixtures/ProductFixtures.php
namespace AppDataFixtures;
use AppEntityProduct;
use DoctrineBundleFixturesBundleFixture;
use DoctrinePersistenceObjectManager;
use FakerFactory;
class ProductFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
$faker = Factory::create('ru_RU');
for ($i = 0; $i < 50; $i++) {
$product = new Product();
$product->setName($faker->words(3, true));
$product->setDescription($faker->paragraph());
$product->setPrice($faker->randomNumber(5, false));
$product->setCreatedAt($faker->dateTimeThisYear);
$manager->persist($product);
// Сохраняем ссылку для использования в других фикстурах
$this->addReference('product_' . $i, $product);
}
$manager->flush();
}
}
А вот когда связи начинали закручиваться — тут уже приходилось голову ломать. Волнение ебать начиналось настоящее.
- Ссылки (References): Чтобы, например, не тыкать заказы (
Order) в пустоту, а привязать к реальному пользователю (User) из другой фикстуры. Делали так:// В OrderFixtures $user = $this->getReference('user_admin'); $order->setCustomer($user);Главное — не перепутать ключи, а то получишь
ReferenceNotFoundException, и всё, приехали. - Зависимые фикстуры: Чтобы не гадать, что загрузится раньше — пользователи или их заказы, — использовали
dependencies. Порядок — наше всё. - Пургатор (Purger): Когда нужно было всё снести и начать с чистого листа, особенно если в базе были связи по внешним ключам. Флаг
--purge-with-truncateбыл нашим спасителем, иначе каскадное удаление могло всё похерить.
Были, конечно, и другие эксперименты. В одном проекте, например, внедрили AliceBundle. Суть в том, что фикстуры можно было описывать в YAML-файлах. Для части команды, которая не хотела вникать в PHP-код ради генерации данных, это было спасением. Но, честно говоря, когда логика усложнялась, YAML-файлы превращались в пиздопроебибну с кучей вложенностей, и проще было вернуться к старому доброму PHP. В общем, инструмент на любителя, но для простых случаев — вполне ничего.