定位
Symfony 常被当成「Laravel 的竞争对手」,其实它更像PHP 的标准库。
Laravel 内部大量使用 Symfony 的组件:HttpFoundation(请求响应对象)、Console(命令行)、Finder(文件查找)、VarDumper(调试)、Process(子进程)、Routing、EventDispatcher。
直接拿 Symfony 全栈框架写业务的人不多,但几乎每个 PHP 项目都在用它的组件。
安装
# 全栈项目
composer create-project symfony/skeleton my-app
cd my-app
composer require webapp # 装 Web 相关整套
1. 或者只用单个组件(更常见)
composer require symfony/http-foundation
两个层面的 Symfony
层面一:组件(大多数人在用的部分)
不装框架也能单独用。比如只要一个「请求对象」:
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationJsonResponse;
$request = Request::createFromGlobals();
$name = $request->query->get('name', 'world');
$response = new JsonResponse(['hello' => $name]);
$response->send();
这就是 HttpFoundation 的价值:把 $_GET、$_POST、$_SERVER 这些超全局变量封装成对象,可测试、可注入。
ThinkPHP 也用了一部分 Symfony 组件。
层面二:全栈框架
symfony/skeleton + webapp 包,包含路由、控制器、Twig 模板、Doctrine ORM、表单、安全、验证。
核心概念
1. 依赖注入容器
Symfony 的核心。服务在 config/services.yaml 里注册,框架自动注入:
services:
AppServiceMailer:
arguments:
$dsn: '%env(MAILER_DSN)%'
控制器里直接类型标注就能拿到:
class UserController
{
public function __construct(private Mailer $mailer) {}
}
这套容器 Laravel 也在用(Laravel 的服务容器是 Symfony 容器的简化版思路)。
2. Bundle 机制
Symfony 的功能以 Bundle 组织。第三方库、你自己的业务模块都可以是 Bundle。
这比 Laravel 的 ServiceProvider 更重,但也更结构化——大型项目里模块边界更清晰。
3. 配置与环境的分离
config/packages/ 下按环境分文件:dev/、prod/、test/。同一个配置项在不同环境用不同值,不用写 if (app()->environment())。
常见坑
① 以为 Symfony 慢
Symfony 的全栈框架启动确实比 Laravel 慢(Bundle 多),但配上 OPcache 和缓存预热后,生产环境差距不大。组件层面更是没有额外开销。
② 版本碎片化
Symfony 有多个 LTS 分支同时维护。搜到一篇教程,先确认它讲的是哪个版本——4.x、5.x、6.x、7.x 的写法差异不小。
③ 组件版本要锁
单独用组件时,不同组件的版本需要兼容。建议一次性 composer require symfony/http-foundation symfony/console 让 composer 自己解析,别一个个装。
什么时候选它
组件层面(推荐大多数人这么用): – 需要一个规范的请求/响应对象 – 需要 CLI 工具框架 – 需要文件查找、进程管理、调试输出这些基础设施
全栈层面: – 企业项目,需要高度定制 – 团队愿意维护自己的技术栈组合 – 项目生命周期长,看重长期可维护性
不选全栈的场景:中小项目(Laravel 效率高得多)、团队没有 Symfony 经验。
一个务实建议
先学 Laravel,再理解 Symfony 组件。
Laravel 把 Symfony 的组件包装得很好用,日常开发不用管底层。等到需要定制(比如换掉某个组件、写自己的 HTTP 内核)时,再去看 Symfony 的实现——那时候你已经知道这些组件在解决什么问题,学起来快得多。
反过来先啃 Symfony 全栈,容易在 Bundle、编译器 Pass、标签这些概念里迷路。