Symfony

技术栈
后端框架
phpenterprisecomponentstwigdoctrinebundles

概览

Symfony\n\nSymfony 是 PHP 生态中最成熟的企业级框架,由 SensioLabs 于 2005 年创建。它以可复用的 PHP 组件为核心,被众多项目(包括 Laravel)作为底层依赖。\n\n### 核心特性\n\n- 可复用组件:50+ 独立组件(HttpFoundation、Routing、Console 等)\n- Twig 模板引擎:快速、安全、灵活的模板系统\n- Doctrine ORM:强大的数据库抽象层\n- Bundle 系统:模块化架构,按需组装\n- 依赖注入容器:企业级 DI/IoC 容器\n- 事件调度器:解耦的事件系统\n- 表单组件:强大的表单构建与验证\n- API Platform:快速构建 REST/GraphQL API

安装

1. 环境准备

  • OS:Linux / macOS / Windows (WSL2)
  • PHP:>= 8.1(Symfony 6.x),>= 8.2(Symfony 7.x)
  • PHP 扩展:Ctype, iconv, JSON, PCRE, Session, SimpleXML, Tokenizer
  • Composer:最新稳定版
  • Symfony CLI:推荐用于开发环境
  • 数据库:MySQL 8+ / PostgreSQL 13+ / SQLite

2. 安装命令

安装 Symfony CLI

# macOS
brew install symfony-cli/tap/symfony-cli

# Linux
curl -1sLf 'https://dl.cloudsmith.io/public/symfony/stable/setup.deb.sh' | sudo -E bash
sudo apt install symfony-cli

# Windows
scoop install symfony-cli

创建新项目

# 传统 Web 应用
symfony new my-project --webapp

# 微服务 / API 最小项目
symfony new my-api

# 通过 Composer
composer create-project symfony/skeleton my-project
cd my-project
composer require webapp  # 添加 Web 功能

启动开发服务器

symfony serve -d
# 访问 http://localhost:8000

3. 常见安装问题

flex 插件缺失

composer require symfony/flex

权限问题

chmod -R 775 var/

国内加速

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

SSL 证书验证失败

# 开发环境临时关闭
symfony serve --allow-http

示例

Hello World - 控制器与路由.md

Hello World:Symfony 控制器与路由

目标

创建 Symfony 最小 API 端点,展示路由注解、控制器和 JSON 响应。

完整代码

1. 创建控制器

php bin/console make:controller HelloController

2. 编辑 src/Controller/HelloController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;

class HelloController extends AbstractController
{
    #[Route('/api/hello', name: 'hello_index', methods: ['GET'])]
    public function index(): JsonResponse
    {
        return $this->json([
            'message' => 'Hello, Vibe!',
            'framework' => 'Symfony',
            'php_version' => PHP_VERSION,
            'timestamp' => (new \DateTimeImmutable())->format(\DateTimeInterface::ATOM),
        ]);
    }

    #[Route('/api/hello/{name}', name: 'hello_greet', methods: ['GET'])]
    public function greet(string $name): JsonResponse
    {
        return $this->json([
            'message' => "Hello, {$name}!",
            'powered_by' => 'Symfony',
        ]);
    }
}

运行步骤

symfony serve -d
# 或 php -S localhost:8000 -t public/

预期输出

curl http://localhost:8000/api/hello
# {"message":"Hello, Vibe!","framework":"Symfony","php_version":"8.3.0","timestamp":"2024-01-01T00:00:00+00:00"}

curl http://localhost:8000/api/hello/World
# {"message":"Hello, World!","powered_by":"Symfony"}

教程

入门篇 - 构建 Todo API.md

Symfony 入门教程:构建 Todo API

1. 背景

Symfony 是 PHP 企业级首选框架。本教程带你构建一个 Todo REST API,掌握控制器、ORM (Doctrine)、验证和序列化的核心用法。

2. 前置概念

概念 说明
Entity Doctrine ORM 映射到数据库表
Repository 实体查询类
Validation Symfony Validator 约束验证
Serializer 对象 ↔ JSON 序列化
Maker Bundle make: 命令快速生成代码

3. 分步操作

步骤一:创建项目

symfony new todo-api --webapp
cd todo-api

步骤二:创建 Todo 实体

php bin/console make:entity Todo

按提示输入字段:

  • titlestring255 → not null
  • descriptiontext → nullable
  • completedboolean → default false

编辑 src/Entity/Todo.php 添加验证:

<?php

namespace App\Entity;

use App\Repository\TodoRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

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

    #[ORM\Column(length: 255)]
    #[Assert\NotBlank, Assert\Length(min: 3, max: 255)]
    private ?string $title = null;

    #[ORM\Column(type: 'text', nullable: true)]
    private ?string $description = null;

    #[ORM\Column]
    private bool $completed = false;

    // getters & setters...
}

步骤三:迁移数据库

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

步骤四:创建控制器

php bin/console make:controller TodoController
<?php

namespace App\Controller;

use App\Entity\Todo;
use App\Repository\TodoRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Validator\ValidatorInterface;

#[Route('/api/todos')]
class TodoController extends AbstractController
{
    #[Route('', methods: ['GET'])]
    public function index(TodoRepository $repo): JsonResponse
    {
        return $this->json($repo->findAll());
    }

    #[Route('', methods: ['POST'])]
    public function create(Request $request, EntityManagerInterface $em, ValidatorInterface $validator): JsonResponse
    {
        $data = json_decode($request->getContent(), true);
        $todo = new Todo();
        $todo->setTitle($data['title'] ?? '');
        if (isset($data['description'])) $todo->setDescription($data['description']);

        $errors = $validator->validate($todo);
        if (count($errors) > 0) {
            return $this->json(['errors' => (string) $errors], 422);
        }

        $em->persist($todo);
        $em->flush();

        return $this->json($todo, 201);
    }

    #[Route('/{id}', methods: ['GET'])]
    public function show(Todo $todo): JsonResponse
    {
        return $this->json($todo);
    }

    #[Route('/{id}', methods: ['PUT'])]
    public function update(Request $request, Todo $todo, EntityManagerInterface $em): JsonResponse
    {
        $data = json_decode($request->getContent(), true);

        if (isset($data['title'])) $todo->setTitle($data['title']);
        if (isset($data['description'])) $todo->setDescription($data['description']);
        if (isset($data['completed'])) $todo->setCompleted($data['completed']);

        $em->flush();

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

    #[Route('/{id}', methods: ['DELETE'])]
    public function delete(Todo $todo, EntityManagerInterface $em): JsonResponse
    {
        $em->remove($todo);
        $em->flush();
        return $this->json(null, 204);
    }
}

4. 验证

curl -X POST http://localhost:8000/api/todos \
  -H "Content-Type: application/json" \
  -d '{"title":"学习 Symfony"}'

curl http://localhost:8000/api/todos

5. 思考题

  1. 如何用 DTO 解耦请求数据和实体?
  2. 如何使用 API Platform 代替手动编写 CRUD?
  3. 如何添加 JWT 认证保护 API?

参考资料

  1. [1] Symfony Team. Symfony Documentation. Symfony Docs, 2026. https://symfony.com/doc
  2. [2] Symfony Team. Symfony Official Site. Symfony.com, 2026. https://symfony.com/
  3. [3] Symfony Team. Symfony Framework GitHub Repository. GitHub, 2026. https://github.com/symfony/symfony
  4. [4] Symfony Team. Symfony GitHub Organization. GitHub, 2026. https://github.com/symfony
  5. [5] Symfony Team. Symfony Documentation Repository. GitHub, 2026. https://github.com/symfony/symfony-docs
  6. [6] Symfony Team. Installing and Setting up the Symfony Framework. Symfony Docs, 2026. https://symfony.com/doc/current/setup.html
  7. [7] Symfony Team. Symfony Releases. Symfony.com, 2026. https://symfony.com/releases
  8. [8] Fabien Potencier. Symfony: The Fast Track. Symfony Book, 2026. https://symfony.com/book
  9. [9] Symfony Team. Symfony Demo Application. GitHub, 2026. https://github.com/symfony/demo
  10. [10] Symfony Team. Symfony Recipes Repository. GitHub, 2026. https://github.com/symfony/recipes
  11. [11] François Zaninotto, Fabien Potencier. The Definitive Guide to symfony. Apress / O'Reilly Learning, 2007. https://www.oreilly.com/library/view/the-definitive-guide/9781590597866/
  12. [12] Sohail Salehi. Mastering Symfony. Packt / O'Reilly Learning, 2014. https://www.oreilly.com/library/view/mastering-symfony/9781784390310/
  13. [13] Pawel Kita. Symfony in action. Leanpub, 2025. https://leanpub.com/symfonyinaction
  14. [14] Mouna Laaziri, Khaoula Benmoussa, Samira Khoulji, et al.. A comparative study of Laravel and Symfony PHP frameworks. International Journal of Electrical and Computer Engineering, 2019. doi:10.11591/ijece.v9i1.pp704-712 https://ijece.iaescore.com/index.php/IJECE/article/view/11601
  15. [15] Mouna Laaziri, Khaoula Benmoussa, Samira Khoulji, et al.. A comparative study of laravel and symfony PHP frameworks. ResearchGate, 2019. https://www.researchgate.net/publication/330656221_A_comparative_study_of_laravel_and_symfony_PHP_frameworks
  16. [16] Mouna Laaziri, Khaoula Benmoussa, Samira Khoulji, et al.. A comparative study of laravel and symfony PHP frameworks. Academia.edu, 2019. https://www.academia.edu/43611052/A_comparative_study_of_laravel_and_symfony_PHP_frameworks
  17. [17] Symfony 中文文档维护者. Symfony 中文文档. Read the Docs, 2026. https://symfony-docs-zh-cn.readthedocs.io/
  18. [18] PHP Documentation Group. PHP Manual. PHP.net, 2026. https://www.php.net/manual/en/
  19. [19] Composer Team. Composer Documentation. Composer Docs, 2026. https://getcomposer.org/doc/
  20. [20] PHP-FIG. PHP Standards Recommendations. PHP-FIG, 2026. https://www.php-fig.org/psr/