Symfony 实体
最后修改时间:2025 年 3 月 4 日
Symfony 实体教程展示了如何在 Symfony 应用程序中创建实体。
Symfony
Symfony 是领先的 PHP 框架之一。它是一套可重用的 PHP 组件,也是一个用于 Web 项目的 PHP 框架。Symfony 于 2005 年作为免费软件发布。Symfony 的灵感来自于 Django、RoR 和 Spring 框架。
实体
实体是一个需要持久化的轻量级领域对象。通常,实体代表关系数据库中的一个表,每个实体实例对应表中的一行。
存储库是对持久化功能的抽象。它允许存储、检索和搜索实体对象。本质上,存储库是实体对象的集合。
Symfony 实体示例
在下面的示例中,我们将处理 City
实体。
$ symfony new syment --version=7.2 --webapp $ cd syment
我们使用 --webapp
选项创建一个新的 Symfony 7.2 项目,该选项包含 Web 应用程序的常用捆绑包,然后导航到项目目录。
$ php bin/console --version Symfony 7.2.0 (env: dev, debug: true)
我们使用的是 Symfony 7.2.0 版本。
$ composer require symfony/orm-pack
我们安装 Doctrine ORM 捆绑包,其中包含注解和其他必要的依赖项。annot
捆绑包不再需要单独安装,因为它已包含在 symfony/orm-pack
中。
$ composer require --dev orm-fixtures maker
为了开发目的,我们安装了 fixtures 和 maker 捆绑包。Fixtures 将假数据加载到数据库中,而 maker 捆绑包则有助于脚手架的生成。
DATABASE_URL="sqlite:///%kernel.project_dir%/var/ydb.db"
在 .env
文件中,我们定义了数据库 URL。在此示例中,为简化起见,我们使用 SQLite。
$ php bin/console doctrine:database:create
doctrine:database:create
命令会根据提供的 URL 创建一个新数据库。
$ php bin/console make:entity
使用 make:entity
命令,我们创建了一个新的 City
实体。这将生成 src/Entity/City.php
和 src/Repository/CityRepository.php
。我们添加了两个属性:name
(字符串,255 个字符)和 population
(整数)。
<?php namespace App\Entity; use App\Repository\CityRepository; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: CityRepository::class)] #[ORM\Table(name: 'cities')] class City { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] private ?string $name = null; #[ORM\Column] private ?int $population = null; public function getId(): ?int { return $this->id; } public function getName(): ?string { return $this->name; } public function setName(string $name): static { $this->name = $name; return $this; } public function getPopulation(): ?int { return $this->population; } public function setPopulation(int $population): static { $this->population = $population; return $this; } }
这是更新到 Symfony 7.2 的 City
实体。我们使用 PHP 8 属性语法(例如 #[ORM\Entity]
),而不是 PHPDoc 注解。该实体映射到 cities
表。
<?php namespace App\Repository; use App\Entity\City; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; /** * @extends ServiceEntityRepository<City> * * @method City|null find($id, $lockMode = null, $lockVersion = null) * @method City|null findOneBy(array $criteria, array $orderBy = null) * @method City[] findAll() * @method City[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ class CityRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, City::class); } }
CityRepository
在很大程度上保持不变,但使用了现代 PHP 类型提示和 docblock 约定。
$ php bin/console make:migration
我们使用 make:migration
生成迁移,以便为数据库模式更改添加版本控制。
$ php bin/console doctrine:migrations:migrate
这将应用迁移,创建一个类似 Version20250304120000.php
的文件(时间戳会有所不同)。
<?php declare(strict_types=1); namespace DoctrineMigrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; final class Version20250304120000 extends AbstractMigration { public function getDescription(): string { return 'Create cities table'; } public function up(Schema $schema): void { $this->addSql('CREATE TABLE cities (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, population INTEGER NOT NULL)'); } public function down(Schema $schema): void { $this->addSql('DROP TABLE cities'); } }
迁移文件现在包含描述和简化的特定于 SQLite 的 SQL。
$ php bin/console make:fixtures
我们使用 make:fixtures
创建一个 CityFixtures
类来加载示例数据。
<?php namespace App\DataFixtures; use App\Entity\City; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; class CityFixtures extends Fixture { public function load(ObjectManager $manager): void { $cities = [ ['name' => 'Bratislava', 'population' => 432000], ['name' => 'Budapest', 'population' => 1759000], ['name' => 'Prague', 'population' => 1280000], ['name' => 'Warsaw', 'population' => 1748000], ['name' => 'Los Angeles', 'population' => 3971000], ['name' => 'New York', 'population' => 8550000], ['name' => 'Edinburgh', 'population' => 464000], ['name' => 'Berlin', 'population' => 3671000], ]; foreach ($cities as $data) { $city = new City(); $city->setName($data['name']); $city->setPopulation($data['population']); $manager->persist($city); } $manager->flush(); } }
CityFixtures
类已更新为更简洁的结构,使用了数组和循环。
$ php bin/console doctrine:fixtures:load
此命令将 fixture 数据加载到 cities
表中。
<?php namespace App\Controller; use App\Repository\CityRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class CityController extends AbstractController { #[Route('/cities', name: 'cities')] public function index(CityRepository $cityRepository): JsonResponse { $cities = $cityRepository->findAll(); if (empty($cities)) { return new JsonResponse(['message' => 'No data found'], Response::HTTP_NOT_FOUND); } return $this->json($cities); } }
CityController
使用新的 #[Route]
属性语法,并直接返回 JsonResponse
。响应处理得到了简化。
$ symfony serve
我们启动 Symfony 开发服务器。
$ curl localhost:8000/cities [{"id":1,"name":"Bratislava","population":432000}, {"id":2,"name":"Budapest","population":1759000}, {"id":3,"name":"Prague","population":1280000}, {"id":4,"name":"Warsaw","population":1748000}, {"id":5,"name":"Los Angeles","population":3971000}, {"id":6,"name":"New York","population":8550000}, {"id":7,"name":"Edinburgh","population":464000}, {"id":8,"name":"Berlin","population":3671000}]
我们使用 curl
测试端点并检索 JSON 数据。
在本教程中,我们使用现代 PHP 和 Symfony 功能,在 Symfony 7.2 应用程序中处理了实体。
列出 所有 Symfony 教程。