虚拟主机怎么配置?让不同 PHP 项目使用独立域名进行本地开发
本地开发 PHP 项目时,如果所有程序都通过 localhost 访问,项目数量一多就容易混淆。例如一个项目位于 C:\xampp\htdocs\project1,另一个项目位于 C:\xampp\htdocs\project2,每次访问都需要记住不同的目录路径。更方便的做法,是让每个项目拥有自己的本地域名,例如 project1.local 和 project2.local。
这里需要先澄清一个概念。多个项目并不是“共用一个 VirtualHost”,而是运行在同一个 Apache 服务实例上,由多个 VirtualHost 分别负责不同域名。Apache 根据浏览器请求中的域名,把请求交给对应的项目目录。这样既可以区分不同项目,也能够更接近真实服务器上的域名访问方式。
Windows 本地虚拟主机通常涉及三个部分:hosts 文件、Apache VirtualHost 配置以及项目目录。三者必须相互对应。
首先修改 Windows 的 hosts 文件。文件位置通常是:
C:\Windows\System32\drivers\etc\hosts
使用管理员权限打开编辑器,然后加入:
127.0.0.1 project1.local
127.0.0.1 project2.local
这里不要求域名必须使用小写,DNS 名称本身不区分大小写。实际开发中采用统一的小写命名只是为了避免人为混乱。
保存之后,可以打开命令提示符测试:
ping project1.local
或者使用:
nslookup project1.local
不过需要注意,nslookup 在某些情况下主要查询 DNS 服务,并不能完全代表系统 hosts 解析路径。更直接的测试方式是使用:
curl http://project1.local
如果 Apache 已经配置正确,就应该能够得到对应网站的响应。
接下来配置 Apache。以 XAMPP 为例,常见配置文件是:
C:\xampp\apache\conf\extra\httpd-vhosts.conf
同时需要确认主配置文件 httpd.conf 中已经加载了这个文件。如果下面这一行前面存在 #,需要根据实际安装环境取消注释:
Include conf/extra/httpd-vhosts.conf
然后可以配置第一个项目:
ServerName project1.local
DocumentRoot "C:/xampp/htdocs/project1"
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
第二个项目则使用另外一个域名和目录:
ServerName project2.local
DocumentRoot "C:/xampp/htdocs/project2"
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
这样,当浏览器访问 http://project1.local 时,Apache 会把请求交给 project1;访问 http://project2.local 时,则交给 project2。
这也是虚拟主机最重要的作用:同一个服务器、同一个80端口,可以根据请求域名把流量分配给不同的网站。因此,不需要为了两个 PHP 项目分别使用 80 和 8080。只有当不同服务确实需要监听不同端口时,才需要配置不同端口。
配置完成后,最好先检查 Apache 配置语法,而不是直接反复重启。XAMPP 可以通过 Apache 控制面板查看错误,也可以在命令行运行 Apache 提供的配置测试命令。常见命令是:
httpd.exe -t
如果输出 Syntax OK,说明基本语法没有问题。如果出现错误,则应该先解决配置文件中的语法问题。
修改配置后需要重新加载或重启 Apache。否则新配置可能尚未进入运行中的 Apache 进程。
Windows 本地虚拟主机最容易出现的问题之一,是Apache虽然启动正常,但访问所有域名时却进入同一个项目。这通常与VirtualHost配置、默认虚拟主机或者ServerName没有正确匹配有关。
另一个常见问题是403 Forbidden。出现403时,不应该简单认为“Windows目录权限不足”。Apache访问目录还涉及 配置、文件系统权限、AllowOverride 设置以及项目目录中的 .htaccess。如果项目依赖 .htaccess 实现URL重写,还需要确认 AllowOverride 与对应模块配置符合项目要求。
如果访问页面出现404,则需要检查 DocumentRoot 是否指向正确目录,以及项目本身的入口文件和URL重写规则是否正确。尤其是Laravel、Symfony等框架,网站根目录通常应该指向项目的 public 目录,而不是整个项目目录。
例如Laravel项目更适合配置为:
DocumentRoot "C:/xampp/htdocs/myapp/public"
而不是:
DocumentRoot "C:/xampp/htdocs/myapp"
这不仅关系到路由,也涉及不应该直接暴露给Web服务器访问的项目文件。
本地域名也不一定非要使用 .local。.test 是专门保留给测试用途的顶级域名,因此本地开发中使用 project1.test、project2.test 是一个很常见的选择。.local 在部分网络环境中还可能与本地网络名称解析机制产生关联,因此如果希望减少潜在冲突,可以考虑使用 .test。
如果项目需要HTTPS,则配置会进一步增加。Apache需要监听443端口,并为对应域名配置SSL虚拟主机。例如:
ServerName project1.test
DocumentRoot "C:/xampp/htdocs/project1"
SSLEngine on
SSLCertificateFile "C:/xampp/apache/conf/ssl.crt/project1.crt"
SSLCertificateKeyFile "C:/xampp/apache/conf/ssl.key/project1.key"
AllowOverride All
Require all granted
但HTTPS本地开发还有一个经常被忽略的问题:证书是否被操作系统和浏览器信任。
自己生成一个自签名证书,并不意味着浏览器会自动信任它。访问时可能出现证书不受信任的警告。实际开发中,可以使用本地开发证书工具生成受信任的本地证书,例如使用mkcert为指定本地域名创建证书,再配置到Apache中。
如果使用多个HTTPS本地域名,每个域名都需要正确匹配证书。现代浏览器通过TLS连接中的SNI等信息让同一个443端口承载多个HTTPS虚拟主机,因此同样没有必要为每个项目分配一个不同端口。
端口问题应该单独理解。如果Apache监听80端口,而另一个程序已经占用了80端口,Apache就可能无法启动。Windows下可以使用:
netstat -ano | findstr :80
检查80端口当前由哪个进程使用。然后根据PID进一步确认对应程序。
如果需要使用8080,也可以让Apache监听8080,例如:
Listen 8080
然后配置:
访问地址就变成:
http://project1.test:8080
但这属于端口级别的调整,并不是配置多个项目时的必要条件。
对于日常PHP开发,还可以把每个项目的VirtualHost配置独立保存。随着项目增加,把所有配置塞进一个巨大文件会越来越难维护。可以根据Apache版本和实际配置方式,把站点配置拆分管理,再通过Include统一加载。
排查本地虚拟主机时,可以按照一个固定顺序进行。首先确认hosts是否把域名解析到了正确地址;然后确认Apache是否正在运行以及监听正确端口;接着检查VirtualHost配置是否被加载;之后检查ServerName、DocumentRoot和Directory配置;最后再检查项目自身的PHP、.htaccess、路由以及应用程序错误。
如果想进一步确认Apache到底把某个域名交给了哪个VirtualHost,可以查看Apache启动时加载的虚拟主机配置以及错误日志。相比不断修改配置文件,这种方法更容易定位问题。
Docker环境则是另一种思路。每个PHP项目可以运行在独立容器中,再通过Nginx、Traefik或者其他反向代理,根据域名把请求转发到不同容器。这种方式更接近容器化生产环境,但需要额外处理网络、端口、容器名称和代理配置。对于单机上的几个普通PHP项目,Apache VirtualHost通常已经足够。
本地虚拟主机的价值并不只是把 localhost 换成几个好看的域名。它可以让不同项目拥有独立的Cookie作用域、URL结构和站点配置,也方便测试依赖域名的登录、重定向、回调地址以及部分Web应用功能。不过,本地域名只是开发环境的一部分,生产环境中的DNS、HTTPS证书、反向代理、Web服务器和防火墙仍然需要独立配置。
如果只是开发几个PHP网站,最简单的结构就是:hosts负责“域名指向本机”,Apache VirtualHost负责“域名对应哪个项目”,DocumentRoot负责“网站文件在哪里”。把这三个层次分清楚以后,即使以后增加十几个本地项目,也不需要不断修改Apache端口,只需要增加对应的域名和VirtualHost配置即可。
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
分享 Facebook | X | WhatsApp | LinkedIn
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP