Symfony框架新手入门:PHP环境搭建与Hello World示例
第一次接触 Symfony,不需要先研究服务容器、事件系统或 Doctrine。最合适的入门路径是先把 PHP 和 Composer 环境准备好,创建一个可以运行的 Symfony 项目,再写一个最简单的路由和控制器,让浏览器真正显示出 Hello World!。完成这一遍之后,Symfony 中“URL 如何找到 PHP 代码、代码又如何生成响应”就会比较清楚。
本文使用传统 Web 项目的方式演示。考虑到不同 Symfony 分支对 PHP 版本的要求不同,安装前先确认自己的 PHP 版本,再选择对应的 Symfony 分支,可以避免一开始就在 Composer 依赖检查这里卡住。
一、开始之前,需要准备哪些环境
Symfony 本质上仍然是 PHP 应用,所以最基本的开发环境只有三部分:PHP、Composer,以及一个能够运行项目的本地 Web 服务。Symfony CLI 很方便,但不是框架运行的硬性依赖。
截至本文核对版本信息时,Symfony 8.1 是稳定分支,要求 PHP 8.4 或更高;Symfony 7.4 是 LTS 分支,最低要求 PHP 8.2。对于刚开始学习、机器上已经安装 PHP 8.2 或 PHP 8.3 的读者,直接使用 Symfony 7.4 LTS 更省事。本文后面的完整示例也以 Symfony 7.4 为主。
| 组件 | 本文建议 | 作用 |
|---|---|---|
| PHP | PHP 8.2 或更高 | 运行 Symfony 与项目代码 |
| Composer | 当前可用稳定版 | 安装 Symfony 及第三方 PHP 依赖 |
| Symfony | 7.4 LTS | 本文实际使用的框架分支 |
| Symfony CLI | 推荐安装,但不是必须 | 创建项目、检查环境和启动本地服务 |
先检查 PHP 是否已经安装
打开终端,在任何目录执行:
php -v
如果 PHP 已经正确加入系统的 PATH,会显示版本信息。下面只是格式示例:
示例输出:
PHP 8.2.x (cli)
Copyright (c) The PHP Group
如果出现 command not found: php 或类似提示,说明 PHP 尚未安装,或者已经安装但终端找不到它。此时应该先解决 PHP 安装和 PATH 配置,再继续安装 Symfony。
检查常用 PHP 扩展
Symfony 会使用若干 PHP 基础扩展。可以执行:
php -m
检查输出中是否包含常见的 ctype、iconv、session、SimpleXML 和 tokenizer 等模块。具体要求还会随着 Symfony 分支和项目安装的组件不同而变化,因此 Composer 的依赖检查结果应作为最终判断依据。
确认 Composer 可用
composer --version
示例输出:
Composer version 2.x.x
只要能正常看到 Composer 版本,后面就可以通过它下载 Symfony 以及项目所需的 PHP 包。
二、创建第一个 Symfony 项目
创建项目有两种常见方法:使用 Symfony CLI,或者直接使用 Composer。对于新手,两种方法都值得知道,但实际操作任选一种即可,不需要重复执行。
方法一:使用 Symfony CLI 创建
如果已经安装 Symfony CLI,可以直接执行:
symfony new symfony_hello --version=lts --webapp
cd symfony_hello
--version=lts 表示选择当前长期支持分支,避免把教程绑定在某个很快停止维护的短期版本上。--webapp 会安装传统 Web 应用通常需要的一组 Symfony 包。
如果明确希望按照本文的 Symfony 7.4 环境创建,也可以指定:
symfony new symfony_hello --version="7.4.*" --webapp
cd symfony_hello
方法二:只使用 Composer
没有安装 Symfony CLI 也没关系,可以直接创建 Symfony Skeleton:
composer create-project symfony/skeleton:"7.4.*" symfony_hello
cd symfony_hello
composer require webapp
第一条命令建立 Symfony 的基础项目,第二条进入项目目录,第三条安装传统 Web 应用常用的组件。
三、认识刚创建出来的项目目录
第一次打开 Symfony 项目时不需要把每个目录都研究一遍。为了完成 Hello World,只需要先认识下面几个位置:
symfony_hello/
├── bin/
│ └── console
├── config/
├── public/
│ └── index.php
├── src/
│ └── Controller/
├── templates/
├── var/
├── vendor/
├── .env
├── composer.json
└── composer.lock
public/index.php 是 Web 请求进入应用的重要入口;src/Controller/ 用来放控制器;config/ 保存框架配置;vendor/ 是 Composer 下载的依赖,通常不要手工修改。
bin/console 则是 Symfony 自带的命令行入口。后面检查路由、清理缓存、创建数据库迁移等操作,经常都会使用它。
四、先确认 Symfony 项目本身能够运行
进入项目根目录后,可以执行:
php bin/console about
如果应用可以正常启动,这个命令会输出项目运行环境、PHP 和 Symfony 等基本信息。这里的具体版本取决于你的安装结果,因此不需要和某份教程里的输出逐字一致。
还可以查看项目当前拥有的 Symfony 命令:
php bin/console list
如果这两条命令都能够正常执行,说明 Composer 依赖基本已经安装完成,Symfony 内核也能够被 PHP 正常加载。
五、启动本地开发服务器
安装了 Symfony CLI 时,在项目根目录执行:
symfony server:start
终端会显示本地开发服务器的访问地址。直接打开输出中的地址即可,不必假定所有机器一定使用完全相同的协议和端口。
开发期间希望终端保持可继续输入命令,也可以使用后台启动方式:
symfony server:start -d
需要停止时执行:
symfony server:stop
六、编写第一个 Hello World 控制器
现在进入真正的 Symfony 代码部分。我们希望浏览器访问 /hello 时返回:
Hello World!
在项目中创建文件:
src/Controller/HelloController.php
文件写入下面的完整代码:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HelloController
{
#[Route('/hello', name: 'app_hello', methods: ['GET'])]
public function index(): Response
{
return new Response(
'<h1>Hello World!</h1>' .
'<p>Symfony is running.</p>'
);
}
}
代码虽然不长,但这里已经包含了 Symfony 最基本的三个概念:路由、控制器和响应。
#[Route()] 是做什么的
这一行:
#[Route('/hello', name: 'app_hello', methods: ['GET'])]
告诉 Symfony:当收到路径为 /hello 的 GET 请求时,应该执行紧跟在下面的 index() 方法。
app_hello 是这条路由的名称。浏览器并不会看到它,但以后在程序内部生成 URL 时可以通过路由名称引用这条地址,而不是到处手写 /hello。
为什么方法必须返回 Response
控制器的职责可以简单理解为:接收请求所需的信息,执行应用逻辑,然后生成 HTTP 响应。
这里没有使用模板,而是直接创建:
new Response(...)
因此浏览器最终收到的响应正文就是我们提供的 HTML 字符串。对于理解框架工作方式而言,这比一开始就加入 Twig 模板更直观。
七、检查路由是否已经被 Symfony 识别
在打开浏览器之前,可以先用 Symfony 自带命令确认路由:
php bin/console debug:router app_hello
如果路由注册正常,会显示与 app_hello 有关的信息,其中应能看到路径 /hello。
也可以列出全部路由:
php bin/console debug:router
这条命令在以后排查“控制器代码明明写了,浏览器为什么还是 404”时很有用。先确认 Symfony 有没有识别路由,比一开始就怀疑 Nginx、PHP 或浏览器更直接。
八、在浏览器验证 Hello World
确认本地服务器正在运行,然后在 Symfony CLI 输出的本地地址后面加上:
/hello
例如开发服务器位于本机 8000 端口时,访问的形式就是:
http://127.0.0.1:8000/hello
正常情况下,页面应该显示:
预期结果:
Hello World!
Symfony is running.
到这里,PHP 环境、Composer 依赖、Symfony 内核、路由系统、控制器以及 HTTP Response 已经连通。这个简单页面比单纯看到 Symfony 欢迎页更有意义,因为其中已经包含了你自己编写的应用代码。
九、把 Hello World 改成带参数的页面
理解固定地址之后,可以稍微向前走一步,让 URL 中的一部分内容传递给控制器。
把 HelloController.php 修改为:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HelloController
{
#[Route('/hello/{name}', name: 'app_hello', methods: ['GET'])]
public function index(string $name): Response
{
return new Response(
'<h1>Hello ' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '!</h1>'
);
}
}
此时访问:
/hello/Symfony
预期页面内容为:
Hello Symfony!
这里的 {name} 是路由参数。Symfony 匹配 URL 后,会把对应部分传给控制器方法的 $name 参数。
示例使用 htmlspecialchars() 对输出进行 HTML 转义,是因为这个值来自 URL,不能假定访问者传入的永远是安全文本。在后面使用 Twig 模板时,正常的模板输出通常会提供自动转义机制。
十、新手最容易遇到的几个问题
1. Composer 提示 PHP 版本不满足要求
先执行:
php -v
composer check-platform-reqs
如果 Composer 要求的 PHP 版本高于本机版本,有两个合理方向:升级 PHP,或者明确创建与当前 PHP 兼容的 Symfony 分支。不要直接使用 --ignore-platform-reqs 强行绕过,因为依赖即使下载成功,运行时仍可能因为 PHP 语法或扩展不兼容而报错。
2. 提示某个 PHP 扩展缺失
先查看当前 CLI 使用的配置文件:
php --ini
再执行:
php -m
确认扩展到底有没有加载。这里特别容易出现一种情况:Web 服务器使用一套 PHP,而终端中的 php 又指向另一套 PHP,因此“浏览器里有扩展,Composer 却说没有”。
3. 访问 /hello 得到 404
优先执行:
php bin/console debug:router app_hello
如果根本找不到 app_hello,重点检查:
HelloController.php是否确实位于src/Controller/;- 命名空间是否为
App\Controller; - 是否正确导入
Symfony\Component\Routing\Attribute\Route; #[Route(...)]的 PHP 语法是否完整。
如果 debug:router 已经能看到路由,但浏览器仍然 404,再检查实际访问的服务器地址、端口以及 Web 服务的入口配置。
4. 修改代码后出现奇怪的旧结果
开发环境通常能够自动处理缓存,但遇到配置修改后表现异常,可以尝试:
php bin/console cache:clear
如果命令本身已经报 PHP 语法错误,应先修复代码,因为清缓存无法解决语法问题。
5. vendor/ 目录可以自己改吗
不应该。vendor/ 是 Composer 管理的第三方依赖目录。重新执行 composer install 或更新依赖时,里面的内容可能被重新生成。
自己的业务代码主要放在 src/,模板放在 templates/,应用配置放在 config/。第三方包需要通过 composer.json 和 Composer 管理。
十一、学完 Hello World 后应该理解什么
到这里不需要记住 Symfony 的全部目录和命令。对入门来说,更重要的是把下面这条主线弄明白:
- PHP 是 Symfony 的运行基础,版本和扩展必须满足项目依赖。
- Composer 根据
composer.json安装 Symfony 和第三方包。 - 浏览器发来的请求进入 Symfony 应用。
- 路由根据 URL 判断应该执行哪个控制器。
- 控制器执行 PHP 代码,并返回
Response。 - Response 最终变成浏览器看到的页面内容。
十二、接下来应该学什么
Hello World 跑通之后,下一步不建议马上进入复杂的数据库设计。更自然的顺序是先把当前请求流程继续向前扩展:
- 学习 Twig,把控制器里的 HTML 字符串移到模板文件中;
- 学习多个路由、路由参数和路由名称;
- 理解
Request,读取 GET、POST 等请求数据; - 理解 Symfony 服务和依赖注入;
- 再学习 Doctrine ORM、数据库迁移和实体;
- 最后逐渐加入表单、验证、登录认证等 Web 项目功能。
这条顺序的好处是,每增加一个概念,都能够接在已经跑通的 Hello World 请求链路上。比如学习 Twig,只是把“控制器直接生成 HTML”改为“控制器调用模板生成 HTML”;学习数据库,则是在控制器生成 Response 之前增加数据读取过程。
总结
Symfony 新手入门的关键并不是一次掌握整个框架,而是先建立一个真正能够运行的最小项目。准备好 PHP 与 Composer 后,用 Symfony CLI 或 Composer 创建项目,在 src/Controller/ 中编写带有 #[Route] 的控制器,再返回一个 Response,就已经完成了 Symfony 最基本的 Web 请求流程。
如果浏览器能够正确显示 Hello World!,说明 PHP、Composer 依赖、Symfony 内核、本地服务器、路由和控制器都已经能够协同工作。后续学习 Twig、数据库和依赖注入,本质上都是在这条已经打通的流程上继续增加功能。
版本说明:文中的 Symfony 分支与 PHP 最低版本信息按照 Symfony 官方 Releases 与安装文档于 2026 年 9 月核对。Symfony 版本会继续更新,实际新建项目时应同时参考 Composer 的依赖检查结果以及所选 Symfony 分支的官方技术要求。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









