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 教程。