发布于 2026-01-06 5 阅读
0

使用 Doctrine 和 MySQL 在 Symfony 中构建动态 API DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

使用 Doctrine 和 MySQL 在 Symfony 中构建动态 API

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

通过连接到真正的数据库,将您的 Symfony API 提升到一个新的水平。在本博客中,您将学习如何使用 Doctrine ORM 和 MySQL 来存储、检索和提供动态数据,使您的后端能够兼容 React、Vue、Angular 或任何现代前端框架。

使用 Doctrine 和 MySQL 在 Symfony 中构建动态 API

指数

  1. 介绍
    • 步骤 1:在 Symfony 中设置数据库配置
    • 步骤 2:安装 Doctrine ORM
    • 步骤 3:创建实体
    • 步骤 4:运行迁移
      • 生成迁移文件
      • 将迁移应用到数据库
      • 确认表格已创建
    • 步骤五:从数据库添加和检索产品
      • 创建固定装置类
      • 将赛程表加载到数据库中
      • 更新 API 控制器以从数据库获取数据
    • 步骤 6:在 React 中查看数据
  2. 统计数据
  3. 要点总结
  4. 有趣的事实
  5. 常见问题解答
  6. 结论
  7. 作者简介
  8. SEO设置
  9. 标签

介绍

当 API 提供的是真实、动态的数据而非固定、硬编码的响应时,其价值将大大提升。在本指南中,我们将扩展 Symfony API,使其能够连接 MySQL 数据库,从而实现数据的实时存储、检索和返回。我们将使用 Doctrine ORM 将数据库表映射到 PHP 实体,运行迁移来设置数据库模式,并将数据集成到 API 端点中。最终,您将拥有一个功能齐全、基于数据库的 API,可以随时为任何前端应用程序提供服务。

“移山者始于搬起小石。”——孔子

步骤 1:在 Symfony 中设置数据库配置
在存储和检索数据之前,Symfony 需要知道如何连接到您的数据库。这在项目根目录下的 .env 文件中进行配置。
在编辑器中打开 .env 文件,找到 DATABASE_URL 行。

DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
Enter fullscreen mode Exit fullscreen mode

请将其替换为您的 MySQL 连接详细信息。例如:

DATABASE_URL="mysql://root:root@127.0.0.1:3306/symfony-app?serverVersion=8.0.32&charset=utf8mb4"
Enter fullscreen mode Exit fullscreen mode

各部分说明:
root:root:数据库用户名和密码。127.0.0.1
:3306:MySQL 运行所在的主机和端口。symfony
:数据库名称。serverVersion
=8.0.32:您正在使用的 MySQL 版本。charset
=utf8mb4:字符编码,用于完全支持 Unicode(包括表情符号)。

提示:将敏感凭据存储在 .env.local 而不是 .env 中,这样它们就不会被提交到版本控制系统中。

步骤 2:安装 Doctrine ORM
Doctrine 是 Symfony 的默认 ORM(对象关系映射器)。它充当 PHP 对象(实体)和数据库表之间的桥梁。我们将使用它来创建表、存储数据,并在 API 中获取数据。

要安装 Doctrine ORM 及相关工具,请运行以下命令:

composer require symfony/orm-pack
composer require --dev doctrine/doctrine-fixtures-bundle
Enter fullscreen mode Exit fullscreen mode

这些软件包的功能:

  • symfony/orm-pack:安装 Doctrine ORM、数据库迁移和配置文件。
  • doctrine/doctrine-fixtures-bundle:允许您加载用于测试的示例数据。(可选,但在开发过程中很有用)

安装完成后,Symfony 会创建一个默认的 config/packages/doctrine.yaml 文件,用于存储 Doctrine 的设置。它还会自动使用您在步骤 1 中设置的 DATABASE_URL。

要验证 Doctrine 是否已安装,请运行:

php bin/console doctrine:database:create

Enter fullscreen mode Exit fullscreen mode

如果一切配置正确,您将看到一条消息,确认数据库已创建。

Created database `symfony-app` for connection named default
Enter fullscreen mode Exit fullscreen mode

步骤 3:创建实体

上一篇博客中,我们的 `/api/products` 接口返回的是硬编码的 JSON 数据。
现在,我们将通过将其连接到存储真实产品条目的数据库表,使其动态化。
为此,我们需要一个 `Product` 实体,Doctrine ORM 会将其映射到数据库表。
在 Symfony 中,实体代表一个数据库表,每个属性都映射到一列。我们将创建一个包含 `title`、`description` 和 `createdAt` 字段的 `Product` 实体。

在终端中运行以下命令:

php bin/console make:entity

Enter fullscreen mode Exit fullscreen mode

出现提示时,请输入:

定义产品实体,包括标题、描述和创建时间字段。

Symfony 会生成 src/Entity/Product.php 文件。
它看起来会像这样:

<?php

namespace App\Entity;

use App\Repository\ProductRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

    #[ORM\Column(type: Types::TEXT)]
    private ?string $description = null;

    #[ORM\Column]
    private ?\DateTimeImmutable $createdAt = null;

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

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

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

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): static
    {
        $this->description = $description;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeImmutable $createdAt): static
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}

Enter fullscreen mode Exit fullscreen mode

步骤 4:运行迁移
现在我们已经创建了 Product 实体,接下来我们将把它变成一个实际的数据库表,以便我们的 API 可以提供真实的数据记录。Symfony 使用 Doctrine 迁移将实体定义转换为数据库模式更改。运行迁移将在 MySQL 中创建 product 表,其中包含我们在步骤 3 中定义的字段。
生成迁移文件

php bin/console make:migration
Enter fullscreen mode Exit fullscreen mode

使用 make:migration 成功生成迁移文件。

这会在 migrations/ 目录下创建一个新的迁移类。
打开它,你会看到 Doctrine 将要执行的 SQL 语句,例如,创建包含 id、title、description 和 created_at 列的产品表。

将迁移应用到数据库

php bin/console doctrine:migrations:migrate
Enter fullscreen mode Exit fullscreen mode

系统会要求您确认。输入“yes”并按回车键。

使用 doctrine:migrations:migrate 成功应用了迁移。
验证表是否已创建。
登录 MySQL:

mysql -u root -p
Enter fullscreen mode Exit fullscreen mode

然后:

USE symfony-app;
SHOW TABLES;
DESCRIBE product;
Enter fullscreen mode Exit fullscreen mode

你应该能看到你的产品表,其中包含我们在产品实体中定义的列。

至此,我们的 Symfony 应用已准备好从数据库中存储和获取产品数据。下一步,我们将添加一些记录,以便我们的 API 可以返回这些记录,而不是占位符 JSON 数据。

“做得好胜过说得好。”——本杰明·富兰克林

步骤 5:从数据库添加和检索产品
我们将使用 Doctrine Fixtures 插入示例记录。Fixtures 是一种便捷的方式,可以将数据加载到数据库中以进行开发和测试。

使用 Composer 安装 orm-fixtures 包

composer require orm-fixtures --dev
Enter fullscreen mode Exit fullscreen mode

要创建 Fixtures 类,
请运行:

php bin/console make:fixtures
Enter fullscreen mode Exit fullscreen mode

当被问及时:

The class name of the fixtures to create (e.g. AppFixtures):
 > ProductFixtures
Enter fullscreen mode Exit fullscreen mode

Symfony 会创建src/DataFixtures/ProductFixtures.php 文件。
请按如下方式更新它:

<?php

namespace App\DataFixtures;

use App\Entity\Product;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;

class ProductFixtures extends Fixture
{
   public function load(ObjectManager $manager): void
   {
       $products = [
           ['title' => 'Sample Product', 'description' => 'This is a sample product description.'],
           ['title' => 'Another Product', 'description' => 'Another example description.'],
           ['title' => 'Third Product', 'description' => 'Yet another product for testing.'],
       ];

       foreach ($products as $data) {
           $product = new Product();
           $product->setTitle($data['title']);
           $product->setDescription($data['description']);
           // createdAt will be set automatically by the constructor
           $manager->persist($product);
       }

       $manager->flush();
   }
}

Enter fullscreen mode Exit fullscreen mode

我们希望每条记录都有一个创建时间戳,而无需在 fixtures 或表单中设置它。
因此,请更新 src/Entity/Product.php 构造函数。

public function __construct()
{
    $this->createdAt = new \DateTimeImmutable();
}

Enter fullscreen mode Exit fullscreen mode

将赛程表加载到数据库中

php bin/console doctrine:fixtures:load

Enter fullscreen mode Exit fullscreen mode

系统会要求您确认。请输入“是”。Doctrine
会将示例记录插入产品表中。

更新 API 控制器,使其从数据库获取数据。
将 src/Controller/Api/ProductApiController.php 中的硬编码 JSON 替换为数据库查询:

<?php

namespace App\Controller\Api;

use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;

class ProductApiController extends AbstractController
{
    #[Route('/api/products', name: 'api_products', methods: ['GET'])]
    public function index(EntityManagerInterface $em): JsonResponse
    {
        $products = $em->getRepository(Product::class)->findAll();

        $data = [];
        foreach ($products as $product) {
            $data[] = [
                'title' => $product->getTitle(),
                'description' => $product->getDescription(),
            ];
        }

        return $this->json($data);
    }
}

Enter fullscreen mode Exit fullscreen mode

现在,当您访问http://localhost:8000/api/products时,您将看到来自数据库的数据,而不是硬编码的数组。

Symfony 产品 API 结果

步骤 6:在 React 中查看数据
现在,Symfony 不再返回固定数组,而是使用 Doctrine 直接从数据库中获取记录。

打开你的 React 应用,地址是:http://localhost:5173

React 前端现在显示从 Symfony API 获取的产品信息,数据存储在数据库中。

你会看到相同的产品列表界面,但这次内容是通过 Symfony 的 API 从数据库获取的。

“使用 Symfony 构建的 RESTful API 让您可以自由地为从简单的 React 应用到企业级平台等各种应用提供支持,所有应用都拥有简洁的后端。” - SensioLabs 工程团队

统计数据

  • Symfony 的官方使用报告显示,全球有超过 60 万名开发者依靠 Symfony 和 Doctrine ORM 来构建强大的应用程序。
  • 根据Doctrine 的 GitHub 代码库显示,该 ORM 已被下载超过 10 亿次,使其成为使用最广泛的 PHP 数据库抽象层之一。

要点总结

  • Symfony 和 Doctrine 提供了一种简洁的方式来将 API 连接到数据库。
  • 实体将 PHP 类映射到数据库表,使您的代码更具表现力和可维护性。
  • Doctrine 迁移功能可以安全地处理模式更新,无需手动执行 SQL 语句。
  • 夹具使预加载用于开发和测试的样本数据变得简单。
  • 通过将硬编码的 JSON 替换为真正的数据库查询,您的 API 可以立即变得动态且可用于生产环境。

有趣的事实

  • Doctrine ORM 被全球数千个 Symfony 项目使用,使其成为 PHP 生态系统中最经受过实战考验的 ORM 之一。
  • Symfony 的数据库层不仅可以连接到 MySQL,还可以连接到 PostgreSQL、SQLite,甚至 Oracle。
  • 借助 Doctrine 的查询构建器,您可以在 PHP 中编写富有表现力的查询,而无需在 SQL 和 PHP 代码之间切换。

常见问题解答

Q1:我可以在 Symfony 中使用 PostgreSQL 而不是 MySQL 吗?
A:可以。Doctrine 支持多种数据库引擎。您只需更新 .env 文件中的 DATABASE_URL 即可。

问2:生产环境需要使用 fixtures 吗?
答:不需要。fixtures 主要用于开发和测试。在生产环境中,通常通过应用程序或迁移来插入数据。

Q3:如果我之后更改了实体会怎样?
A:您可以运行 php bin/console make:migration,然后运行 ​​php bin/console doctrine:migrations:migrate 来安全地更新数据库架构。

结论

从硬编码数据迁移到数据库驱动的 API 是后端开发中的一个重要里程碑。借助 Symfony、Doctrine 和 MySQL,这一过程简单直接,并为可扩展的应用程序奠定了坚实的基础。一旦您的 API 连接到真实数据,无论它是为 React 前端、移动应用还是其他客户端系统提供支持,您都将开启无限可能。这一步骤将您的 API 从演示版本转变为可供实际应用的成熟版本。

作者简介:Balasaranya Varadhalingam,AddWebSolution的软件工程师,专长于 PHP、Symfony 和 API 开发。

文章来源:https://dev.to/addwebsolutionpvtltd/building-a-dynamic-api-in-symfony-with-doctrine-and-mysql-5gg6