ZetCode

Symfony Fixtures 教程

最后修改时间:2025年3月3日

Symfony Fixtures 教程展示了如何在 AuthorsBooks 实体之间具有多对多关系的情况下使用 fixtures。

Symfony

Symfony 是一套可重用的 PHP 组件,也是一个用于 Web 项目的 PHP 框架。Symfony 于 2005 年发布为自由软件。Fabien Potencier 是 Symfony 的最初作者。Symfony 在很大程度上受到了 Spring 框架的启发。

Fixtures

Fixtures 用于将受控数据集加载到数据库中。它们对于测试和开发很有用。

设置项目

我们首先创建一个新的 Symfony 项目并安装必要的依赖项。

$ composer create-project symfony/skeleton symfony-fixtures "^7.2"
$ cd symfony-fixtures

我们创建一个新的 Symfony 7.2 项目并导航到项目目录。

$ composer require symfony/orm-pack
$ composer require --dev symfony/maker-bundle

我们安装 ORM 包以支持数据库,并安装 maker bundle 来生成代码。

$ composer require --dev doctrine/doctrine-fixtures-bundle

我们安装 fixtures bundle。

创建实体

我们创建两个实体:AuthorBook,它们具有多对多的关系。

$ php bin/console make:entity Author

我们创建 Author 实体,包含字段:name(字符串)。

src/Entity/Author.php
<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Author
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private string $name;

    #[ORM\ManyToMany(targetEntity: Book::class, mappedBy: 'authors')]
    private Collection $books;

    public function __construct()
    {
        $this->books = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getBooks(): Collection
    {
        return $this->books;
    }

    public function addBook(Book $book): void
    {
        if (!$this->books->contains($book)) {
            $this->books->add($book);
            $book->addAuthor($this);
        }
    }

    public function removeBook(Book $book): void
    {
        if ($this->books->contains($book)) {
            $this->books->removeElement($book);
            $book->removeAuthor($this);
        }
    }
}

Author 实体与 Book 实体具有多对多的关系。

$ php bin/console make:entity Book

我们创建 Book 实体,包含字段:title(字符串)。

src/Entity/Book.php
<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Book
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private string $title;

    #[ORM\ManyToMany(targetEntity: Author::class, inversedBy: 'books')]
    private Collection $authors;

    public function __construct()
    {
        $this->authors = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): string
    {
        return $this->title;
    }

    public function setTitle(string $title): void
    {
        $this->title = $title;
    }

    public function getAuthors(): Collection
    {
        return $this->authors;
    }

    public function addAuthor(Author $author): void
    {
        if (!$this->authors->contains($author)) {
            $this->authors->add($author);
            $author->addBook($this);
        }
    }

    public function removeAuthor(Author $author): void
    {
        if ($this->authors->contains($author)) {
            $this->authors->removeElement($author);
            $author->removeBook($this);
        }
    }
}

Book 实体与 Author 实体具有多对多的关系。

$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate

我们生成并运行迁移以创建数据库表。

使用 Fixtures

我们使用 fixtures 来填充数据库的示例数据。

src/DataFixtures/AppFixtures.php
<?php

declare(strict_types=1);

namespace App\DataFixtures;

use App\Entity\Author;
use App\Entity\Book;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;

class AppFixtures extends Fixture
{
    public function load(ObjectManager $manager): void
    {
        // Create authors
        $author1 = new Author();
        $author1->setName('J.K. Rowling');
        $manager->persist($author1);

        $author2 = new Author();
        $author2->setName('George R.R. Martin');
        $manager->persist($author2);

        // Create books
        $book1 = new Book();
        $book1->setTitle('Harry Potter and the Philosopher\'s Stone');
        $book1->addAuthor($author1);
        $manager->persist($book1);

        $book2 = new Book();
        $book2->setTitle('A Game of Thrones');
        $book2->addAuthor($author2);
        $manager->persist($book2);

        $book3 = new Book();
        $book3->setTitle('Harry Potter and the Chamber of Secrets');
        $book3->addAuthor($author1);
        $manager->persist($book3);

        // Save all entities
        $manager->flush();
    }
}

AppFixtures 类使用示例作者和书籍填充数据库,建立多对多关系。

$ php bin/console doctrine:fixtures:load

我们将 fixtures 加载到数据库中。

显示数据

我们创建一个路由来显示作者及其书籍。

src/Controller/AuthorController.php
<?php

declare(strict_types=1);

namespace App\Controller;

use App\Entity\Author;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class AuthorController extends AbstractController
{
    #[Route('/authors', name: 'author_list')]
    public function list(EntityManagerInterface $em): Response
    {
        $authors = $em->getRepository(Author::class)->findAll();
        return $this->render('author/list.html.twig', ['authors' => $authors]);
    }
}

AuthorController 提供了一个列出所有作者及其书籍的路由。

templates/author/list.html.twig
{% extends 'base.html.twig' %}

{% block title %}Author List{% endblock %}

{% block body %}
<h1>Author List</h1>
<ul>
    {% for author in authors %}
    <li>
        <strong>{{ author.name }}</strong>
        <ul>
            {% for book in author.books %}
            <li>{{ book.title }}</li>
            {% endfor %}
        </ul>
    </li>
    {% endfor %}
</ul>
{% endblock %}

Twig 模板显示作者及其书籍的列表。

运行示例

$ php bin/console server:start

我们启动开发服务器。

$ curl localhost:8000/authors

我们通过在浏览器中访问 URL 来查看 HTML 中的作者列表。

在本教程中,我们使用 Symfony fixtures 来填充具有多对多关系的 AuthorsBooks 实体的数据库。

列出 所有 Symfony 教程