Symfony 本地 Web 服务器
您可以使用任何 Web 服务器(Apache、nginx、内部 PHP Web 服务器等)运行 Symfony 应用程序。但是,Symfony 提供了自己的 Web 服务器,以提高您在开发应用程序时的效率。
虽然此服务器不适用于生产环境,但它支持 HTTP/2、TLS/SSL、自动生成安全证书、本地域名以及许多其他功能,这些功能您迟早会在开发 Web 项目时需要。此外,该服务器不限于 Symfony,您也可以将其用于任何 PHP 应用程序,甚至 HTML 或单页应用程序。
安装
Symfony 服务器是您symfony
安装 Symfony 时创建的二进制文件的一部分,并支持 Linux、macOS 和 Windows。
提示
Symfony CLI 支持 Bash、Zsh 或 Fish shell 的自动补全。您必须一次安装补全脚本。运行 symfony completion --help
以获取适用于您的 shell 的安装说明。安装并重启终端后,您就可以使用补全功能了(默认情况下,按 Tab 键)。
如果 Symfony CLI 检测到 Symfony 项目,它还将为 composer
命令和 console
命令提供补全。
注意
您可以在 symfony-cli/symfony-cli GitHub 仓库中查看 Symfony CLI 源代码并为其做出贡献。
入门
Symfony 服务器每个项目启动一次,因此您可能会得到多个实例(每个实例监听不同的端口)。这是服务 Symfony 项目的常用工作流程
1 2 3 4 5 6 7 8
$ cd my-project/
$ symfony server:start
[OK] Web server listening on http://127.0.0.1:....
...
# Now, browse the given URL, or run this command:
$ symfony open:local
以这种方式运行服务器会在控制台中显示日志消息,因此您将无法同时运行其他命令。如果您愿意,可以在后台运行 Symfony 服务器
1 2 3 4 5 6 7 8 9
$ cd my-project/
# start the server in the background
$ symfony server:start -d
# continue working and running other commands...
# show the latest log messages
$ symfony server:log
提示
在 macOS 上,当启动 Symfony 服务器时,您可能会看到一个警告对话框,询问“您要允许应用程序接受传入的网络连接吗?”。当运行未签名且未在防火墙列表中列出的应用程序时,会发生这种情况。解决方案是运行此命令来签署 Symfony 二进制文件
1
$ sudo codesign --force --deep --sign - $(whereis -q symfony)
启用 PHP-FPM
注意
必须在本地安装 PHP-FPM 才能使用 Symfony 服务器。
当服务器启动时,它会按顺序检查 web/index_dev.php
、web/index.php
、public/app_dev.php
、public/app.php
。如果找到其中一个,服务器将自动启动并启用 PHP-FPM。否则,服务器将启动时不启用 PHP-FPM,并且在尝试访问浏览器中的 .php
文件时,将显示 Page not found
页面。
提示
当 index.html
和前端控制器(例如 index.php
)都存在时,服务器仍将启动并启用 PHP-FPM,但 index.html
将优先于前端控制器。这意味着当 index.html
文件存在于 public
或 web
中时,它将代替 index.php
显示,而 index.php
将显示例如 Symfony 应用程序。
启用 TLS
在本地浏览应用程序的安全版本对于尽早检测混合内容问题以及运行仅在 HTTPS 中运行的库非常重要。传统上,这非常痛苦且设置复杂,但 Symfony 服务器会自动执行所有操作。首先,运行此命令
1
$ symfony server:ca:install
此命令创建一个本地证书颁发机构,将其注册到您的系统信任存储中,将其注册到 Firefox 中(仅该浏览器需要),并为 localhost
和 127.0.0.1
创建默认证书。换句话说,它为您完成了一切。
提示
如果您在 WSL (Windows Subsystem for Linux) 中执行此操作,则需要手动将新创建的本地证书颁发机构导入 Windows。该文件位于 wsl
中的 ~/.symfony5/certs/default.p12
。最简单的方法是从 wsl
运行以下命令
1
$ explorer.exe `wslpath -w $HOME/.symfony5/certs`
在刚刚打开的文件资源管理器窗口中,双击名为 default.p12
的文件。
在使用 HTTPS 而不是 HTTP 浏览本地应用程序之前,请重启其服务器,停止并再次启动它。
每个项目不同的 PHP 设置
选择不同的 PHP 版本
如果您的计算机上安装了多个 PHP 版本,您可以创建一个名为 .php-version
的文件,放在项目根目录中,告诉 Symfony 使用哪个版本
1 2 3 4 5 6 7
$ cd my-project/
# use a specific PHP version
$ echo 7.4 > .php-version
# use any PHP 8.x version available
$ echo 8 > .php-version
提示
Symfony 服务器会向上遍历目录结构直到根目录,因此您可以在某个父目录中创建一个 .php-version
文件,为该目录下的多个项目设置相同的 PHP 版本。
如果您不记得计算机上安装的所有 PHP 版本,请运行以下命令
1 2 3 4 5
$ symfony local:php:list
# You'll see all supported SAPIs (CGI, FastCGI, etc.) for each version.
# FastCGI (php-fpm) is used when possible; then CGI (which acts as a FastCGI
# server as well), and finally, the server falls back to plain CGI.
覆盖每个项目的 PHP 配置选项
您可以通过在项目根目录中创建一个名为 php.ini
的文件,更改每个项目的任何 PHP 运行时配置选项的值。仅添加您要覆盖的选项
1 2 3 4 5 6
$ cd my-project/
# this project only overrides the default PHP timezone
$ cat php.ini
[Date]
date.timezone = Asia/Tokyo
使用不同 PHP 版本运行命令
当运行不同的 PHP 版本时,使用主 symfony
命令作为 php
命令的包装器非常有用。这使您可以始终根据运行命令的项目选择最合适的 PHP 版本。它还会自动加载 env 变量,这在运行非 Symfony 命令时很重要
1 2 3 4 5 6
# runs the command with the default PHP version
$ php -r "..."
# runs the command with the PHP version selected by the project
# (or the default PHP version if the project didn't select one)
$ symfony php -r "..."
本地域名
默认情况下,项目可以通过 127.0.0.1
本地 IP 的某个随机端口访问。但是,有时最好将域名与它们关联起来
- 当您持续在同一项目上工作时,这更方便,因为端口号可能会更改,但域名不会;
- 某些应用程序的行为取决于其域名/子域名;
- 为了拥有稳定的端点,例如 OAuth2 的本地重定向 URL。
设置本地代理
本地域名之所以成为可能,归功于 Symfony 服务器提供的本地代理。如果您是第一次运行代理,则必须按如下方式配置它
打开您操作系统的代理设置
将以下 URL 设置为自动代理配置的值
http://127.0.0.1:7080/proxy.pac
现在运行此命令以启动代理
1
$ symfony proxy:start
如果代理未按以下部分所述工作,请检查以下内容:
- 某些浏览器(例如 Chrome)需要重新应用代理设置(单击
chrome://net-internals/#proxy
页面上的Re-apply settings
按钮)或在启动代理后完全重启。否则,您将看到“此网页不可用”错误 (ERR_NAME_NOT_RESOLVED
); - 某些操作系统(例如 macOS)默认不将代理设置应用于本地主机和域名。您可能需要从该列表中删除
*.local
和/或其他 IP 地址。 - 配置自动代理时,Windows 操作系统**需要** `localhost` 而不是
127.0.0.1
,否则您将无法从 Windows 中运行的浏览器访问您的本地域名。
定义本地域名
默认情况下,Symfony 为本地域名建议使用 .wip
(代表 *Work in Progress*)。您可以按如下方式为您的项目定义本地域名
1 2
$ cd my-project/
$ symfony proxy:domain:attach my-domain
如果您已按照上一节中的说明安装了本地代理,则现在可以浏览 https://my-domain.wip
以使用新的自定义域名访问您的本地项目。
提示
浏览 http://127.0.0.1:7080 URL 以获取本地项目目录、其自定义域名和端口号的完整列表。
您还可以添加通配符域名
1
$ symfony proxy:domain:attach "*.my-domain"
因此它将匹配所有子域名,例如 https://admin.my-domain.wip
、https://other.my-domain.wip
...
运行控制台命令时,添加 https_proxy
环境变量以使自定义域名生效
1 2 3 4 5 6 7 8
# Example with curl
$ https_proxy=$(symfony proxy:url) curl https://my-domain.wip
# Example with Blackfire and curl
$ https_proxy=$(symfony proxy:url) blackfire curl https://my-domain.wip
# Example with Cypress
$ https_proxy=$(symfony proxy:url) ./node_modules/bin/cypress open
警告
虽然环境变量名称始终以大写形式定义,但 https_proxy
环境变量 的处理方式不同,并且其名称必须以小写形式拼写。
提示
如果您希望使用不同的 TLD,请编辑 ~/.symfony5/proxy.json
文件(其中 ~
表示您的用户目录的路径)并将 tld
选项的值从 wip
更改为任何其他 TLD。
长时间运行的命令
长时间运行的命令(例如编译前端 Web 资源的命令)会阻塞终端,并且您无法同时运行其他命令。Symfony 服务器提供了一个 run
命令来包装它们,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# compile Webpack assets using Symfony Encore ... but do that in the
# background to not block the terminal
$ symfony run -d npx encore dev --watch
# continue working and running other commands...
# from time to time, check the command logs if you want
$ symfony server:log
# and you can also check if the command is still running
$ symfony server:status
Web server listening on ...
Command "npx ..." running with PID ...
# stop the web server (and all the associated commands) when you are finished
$ symfony server:stop
配置文件
您可以使用 .symfony.local.yaml
配置文件设置多个选项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# Sets domain1.wip and domain2.wip for the current project
proxy:
domains:
- domain1
- domain2
http:
document_root: public/ # Path to the project document root
passthru: index.php # Project passthru index
port: 8000 # Force the port that will be used to run the server
preferred_port: 8001 # Preferred HTTP port [default: 8000]
p12: path/to/p12_cert # Name of the file containing the TLS certificate to use in p12 format
allow_http: true # Prevent auto-redirection from HTTP to HTTPS
no_tls: true # Use HTTP instead of HTTPS
daemon: true # Run the server in the background
use_gzip: true # Toggle GZIP compression
no_workers: true # Do not start workers
警告
在此配置文件中设置域名将覆盖您在使用 proxy:domain:attach
命令为当前项目设置的任何域名(当您启动服务器时)。
配置工作进程
如果您希望某些进程与 Web 服务器 (symfony server:start
) 一起自动启动,您可以在 YAML 配置文件中设置它们
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# .symfony.local.yaml
workers:
# built-in command that builds and watches front-end assets
# npm_encore_watch:
# cmd: ['npx', 'encore', 'dev', '--watch']
npm_encore_watch: ~
# built-in command that starts messenger consumer
# messenger_consume_async:
# cmd: ['symfony', 'console', 'messenger:consume', 'async']
# watch: ['config', 'src', 'templates', 'vendor']
messenger_consume_async: ~
# you can also add your own custom commands
build_spa:
cmd: ['npm', '--cwd', './spa/', 'dev']
# auto start Docker compose when starting server (available since Symfony CLI 5.7.0)
docker_compose: ~
提示
您可能希望在某些环境(如 CI)中不启动工作进程。您可以使用 --no-workers
选项在不启动工作进程的情况下启动服务器。
Docker 集成
本地 Symfony 服务器为使用 Docker 的项目提供完整的 Docker 集成。要了解有关 Docker 和 Symfony 的更多信息,请参阅 将 Docker 与 Symfony 结合使用。
当 Web 服务器检测到 Docker Compose 正在为项目运行时,它会自动公开一些环境变量。
通过 docker-compose
API,它会查找用于常见服务的公开端口。当它检测到它知道的服务时,它会使用服务名称来公开环境变量。
考虑以下配置
1 2 3 4
# compose.yaml
services:
database:
ports: [3306]
Web 服务器检测到一个公开端口 3306
的服务正在为项目运行。它理解这是一个 MySQL 服务,并相应地创建环境变量,服务名称 (database
) 作为前缀:DATABASE_URL
、DATABASE_HOST
、...
如果服务不在以下支持列表中,则会设置通用环境变量:PORT
、IP
和 HOST
。
如果 compose.yaml
名称与 Symfony 的约定不匹配,请添加一个标签以覆盖环境变量前缀
1 2 3 4 5 6
# compose.yaml
services:
db:
ports: [3306]
labels:
com.symfony.server.service-prefix: 'DATABASE'
在此示例中,服务名为 db
,因此环境变量将以 DB_
为前缀,但由于 com.symfony.server.service-prefix
设置为 DATABASE
,Web 服务器会创建以 DATABASE_
开头的环境变量,而不是默认 Symfony 配置所期望的。
这是支持的服务列表,包含它们的端口和默认 Symfony 前缀
服务 | 端口 | Symfony 默认前缀 |
---|---|---|
MySQL | 3306 |
|
PostgreSQL | 5432 |
|
Redis | 6379 |
|
Memcached | 11211 |
|
RabbitMQ | 5672 | 5672 |
Elasticsearch | 9200 |
|
MongoDB | 27017 | 27017 |
Kafka | 9092 |
|
MailCatcher | 1080 , 1025 , 25 , 80 |
Blackfire |
8784 |
8707 |
|
Mercure | 80 | 3000 |
您可以为公开 Web 管理界面的服务打开 Web 管理界面
1 2
$ symfony open:local:webmail
$ symfony open:local:rabbitmq
或单击 Web 调试工具栏的“服务器”部分中的链接。
提示
要调试和列出所有导出的环境变量,请运行 symfony var:export --debug
。
提示
对于某些服务,Web 服务器还会公开 CLI 工具理解的与服务相关的环境变量。例如,运行 symfony run psql
将自动将您连接到容器中运行的 PostgreSQL 服务器,而无需指定用户名、密码或数据库名称。
当 Docker 服务正在运行时,浏览 Symfony 应用程序的页面并检查 Web 调试工具栏中的“Symfony 服务器”部分;您会看到“Docker Compose”为“Up”。
注意
如果您不希望为服务公开环境变量,请将 com.symfony.server.service-ignore
标签设置为 true
1 2 3 4 5 6
# compose.yaml
services:
db:
ports: [3306]
labels:
com.symfony.server.service-ignore: true
如果您的 Docker Compose 文件不在项目根目录下,请使用 COMPOSE_FILE
和 COMPOSE_PROJECT_NAME
环境变量来定义其位置,与 docker-compose
相同
1 2 3 4 5
# start your containers:
COMPOSE_FILE=docker/compose.yaml COMPOSE_PROJECT_NAME=project_name docker-compose up -d
# run any Symfony CLI command:
COMPOSE_FILE=docker/compose.yaml COMPOSE_PROJECT_NAME=project_name symfony var:export
注意
如果您有多个 Docker Compose 文件,您可以将它们全部以 :
分隔提供,如 Docker compose CLI env var 参考中所述。
警告
当将 Symfony 二进制文件与 php bin/console
(symfony console ...
) 一起使用时,该二进制文件**始终**使用通过 Docker 检测到的环境变量,并忽略本地环境变量。例如,如果您在 .env.test
文件中设置了不同的数据库名称 (DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/test
),并且您运行 symfony console doctrine:database:drop --force --env=test
,则该命令将删除 Docker 配置中定义的数据库,而不是 “test” 数据库。
警告
与其他 Web 服务器类似,此工具会自动公开 CLI 上下文中所有可用的环境变量。确保未经同意,此本地服务器无法在您的本地网络上访问,以避免安全问题。
Platform.sh 集成
本地 Symfony 服务器提供与 Platform.sh 的完整但可选的集成,Platform.sh 是一项优化的服务,用于在云端运行您的 Symfony 应用程序。它提供诸如创建环境、备份/快照,甚至从本地计算机访问生产数据副本等功能,以帮助调试任何问题。