hosts 文件怎么修改?本地测试多个 PHP 域名时的实用方法
做PHP本地开发时,如果只有一个项目,直接访问 http://localhost/ 通常就够了。但当电脑上同时运行多个PHP项目,而且希望每个项目都有自己的域名,例如 site1.test、site2.test、shop.test,事情就不再只是“把文件放进htdocs目录”这么简单。
这时候需要理解一个非常基础、但又经常被混淆的关系:域名解析和Web服务器到底是谁负责的。
hosts 文件解决的是“这个域名应该找到哪台机器”,Apache或者Nginx解决的则是“找到这台机器以后,应该把这个域名交给哪个网站”。
两者是前后衔接的两个环节。
Windows中的hosts文件位于:
C:\Windows\System32\drivers\etc\hosts
Linux和macOS通常使用:
/etc/hosts
它本质上就是一个本地静态名称解析文件。比如:
127.0.0.1 site1.test
127.0.0.1 site2.test
这两行的意思非常简单:当本机需要解析 site1.test 或 site2.test 时,把它们解析到本机的 127.0.0.1。
这里有一个特别容易出现的错误。
有人认为两个域名指向同一个IP以后,访问第二个域名就会自动变成第一个域名。这是不对的。
例如:
127.0.0.1 site1.test
127.0.0.1 site2.test
两个域名确实指向同一个IP,但浏览器访问的仍然是不同的域名。HTTP请求中的Host信息仍然会告诉Apache或Nginx:“用户访问的是site1.test”还是“site2.test”。
真正决定两个项目是否能够分别打开的,是Web服务器后面的虚拟主机配置。
因此,hosts 文件并不是用来区分不同PHP项目的,它只负责把域名指向正确的IP地址。
在Windows中修改hosts时,需要注意管理员权限。
最简单的方法不是直接双击hosts文件,而是先打开记事本,并使用“以管理员身份运行”,然后在记事本中选择“文件”→“打开”,进入:
C:\Windows\System32\drivers\etc\
文件类型选择“所有文件”,然后打开 hosts。
添加类似:
127.0.0.1 site1.test
127.0.0.1 site2.test
保存即可。
如果直接用普通权限的记事本编辑,通常会因为权限不足无法保存。
还有一个细节非常重要:hosts文件没有必要使用 .com 之类的真实互联网域名。
本地开发更适合使用专门用于测试的域名,例如 .test。例如:
site1.test
site2.test
shop.test
这样可以避免把真实网站域名拿来做本地解析,减少开发过程中产生混淆。
很多教程喜欢写:
*.local.dev
然后声称一条hosts记录就可以让所有子域名自动指向127.0.0.1。
这种说法并不适用于Windows的标准hosts机制。hosts文件本身不提供通配符DNS功能。你不能简单写一行:
127.0.0.1 *.local.dev
然后期待 a.local.dev、b.local.dev、c.local.dev全部自动生效。
如果项目数量不多,直接逐个写hosts记录反而最简单。
例如:
127.0.0.1 wordpress.test
127.0.0.1 shop.test
127.0.0.1 crm.test
接下来才轮到Apache。
假设使用XAMPP中的Apache,可以在虚拟主机配置文件中建立对应关系。例如:
ServerName site1.test
DocumentRoot "C:/xampp/htdocs/site1"
再增加第二个:
ServerName site2.test
DocumentRoot "C:/xampp/htdocs/site2"
这样访问:
http://site1.test
Apache就可以把请求交给:
C:/xampp/htdocs/site1
访问:
http://site2.test
则交给:
C:/xampp/htdocs/site2
这里就能看出hosts和Apache虚拟主机之间的区别。
hosts负责:
site1.test → 127.0.0.1
Apache负责:
site1.test → C:/xampp/htdocs/site1
如果第一步成功、第二步配置错误,浏览器仍然可能能够连接到Apache,但打开的却是错误项目。
例如两个域名都已经正确解析到127.0.0.1,但是Apache没有配置第二个VirtualHost,那么Apache可能把请求交给默认虚拟主机。结果可能是打开第一个网站,也可能出现404、403或者其他响应,具体取决于Apache的配置。
所以“ServerName不一致就一定403”也是不准确的。
Nginx的原理完全一样。
例如:
server {
listen 80;
server_name site1.test;
root C:/nginx/html/site1;
index index.php index.html;
}
第二个项目再建立另一个server块:
server {
listen 80;
server_name site2.test;
root C:/nginx/html/site2;
index index.php index.html;
}
当浏览器发送请求以后,Nginx根据请求中的域名选择对应的server块。
因此,本地多PHP项目实际上形成了这样一条链:
浏览器输入域名 → hosts解析 → 127.0.0.1 → Apache/Nginx监听80端口 → 根据Host选择虚拟主机 → 找到项目目录 → PHP处理程序执行PHP代码。
只要其中任何一个环节出问题,最终都可能表现为“网站打不开”。
这也是排查本地域名问题最有效的方法。
第一步,不要先检查PHP。
先检查域名到底解析到了哪里。
Windows可以执行:
ping site1.test
或者:
nslookup site1.test
不过需要注意,nslookup主要用于DNS查询,并不能完全等同于系统实际的hosts解析行为。因此在Windows上排查本地hosts时,也可以直接使用:
ping site1.test
如果能够看到127.0.0.1,说明基本的名称解析已经符合预期。
第二步检查Apache或Nginx是否真的在监听80端口。
如果浏览器提示“无法连接”,那么问题可能根本还没有到PHP这一层。
第三步检查虚拟主机。
确认:
ServerName
或者Nginx中的:
server_name
是否与浏览器地址栏输入的域名一致。
第四步检查项目目录。
例如Apache配置:
DocumentRoot "C:/xampp/htdocs/site1"
那么这个目录必须确实存在,而且里面应该有项目文件。
如果是PHP项目,还需要进一步确认Apache是否正确连接PHP模块或者PHP-FPM。
如果访问的是:
http://site1.test/test.php
而PHP代码没有执行,显示源码或者返回500错误,那么问题已经不是hosts了,而是PHP运行环境。
还有一个经常被误认为是“DNS问题”的现象:修改hosts之后浏览器仍然访问旧地址。
这时候可以清理Windows DNS缓存:
ipconfig /flushdns
然后重新打开浏览器测试。
但也不要把所有问题都归结为DNS缓存。hosts属于本机名称解析机制,浏览器还可能存在自己的缓存、连接复用等情况。最简单的验证方法是关闭当前页面,重新打开一个新的浏览器窗口,或者使用命令行测试HTTP请求。
例如:
curl -I http://site1.test
如果返回了HTTP状态码,例如200、301、403或者404,至少可以确定请求已经到达Web服务器。
这比单纯盯着浏览器错误页面更加有价值。
如果使用HTTPS,还需要再考虑一个额外问题:证书。
hosts只能解决:
site1.test → 127.0.0.1
它不会自动给这个域名生成HTTPS证书。
如果本地使用:
https://site1.test
那么Apache或Nginx还必须配置443端口和对应证书,否则即使hosts和虚拟主机全部正确,浏览器仍然可能出现证书错误或者连接失败。
Docker环境则更加容易出现误解。
例如在Docker容器里面写:
--add-host=site1.test:127.0.0.1
这里的127.0.0.1指的是“这个容器自己”,并不是Windows宿主机。
如果容器需要访问宿主机上的服务,就不能简单照搬这个写法。在Docker Desktop环境中,通常需要根据实际网络结构使用宿主机对应的地址或Docker提供的宿主机名称机制。
因此,Docker里的hosts问题必须先搞清楚:到底是“宿主机访问容器”,还是“容器访问宿主机”,还是“一个容器访问另一个容器”。
这三个问题的答案完全不同。
对于普通PHP本地开发,如果只是Windows电脑上使用XAMPP、Apache、PHP和MySQL运行几个项目,其实没有必要一开始就引入DNSMasq之类的复杂工具。
三个项目就写三条hosts:
127.0.0.1 site1.test
127.0.0.1 site2.test
127.0.0.1 site3.test
然后给Apache或者Nginx分别配置三个虚拟主机,已经足够。
如果项目非常多,而且需要大量子域名,例如:
api.project.test
admin.project.test
www.project.test
shop.project.test
这时候才有必要考虑本地DNS工具、开发环境代理或者其他自动化方案。
对于绝大多数个人PHP开发环境来说,hosts并不复杂。真正容易出错的地方,是把“域名解析”和“网站选择”混成了一件事情。
hosts只回答一个问题:这个域名应该连接到哪个IP。
Apache或者Nginx再回答另一个问题:这个请求应该进入哪个网站目录。
PHP则负责回答第三个问题:进入这个网站以后,PHP代码应该如何执行。
把这三层分开以后,本地多个PHP域名的问题就会变得非常清楚。
如果浏览器连不上,先查IP和端口;如果打开的是错误项目,查Apache或Nginx虚拟主机;如果PHP不执行,再查PHP环境;如果只有HTTPS出问题,则继续检查证书和443配置。
这样排查,比反复修改hosts文件有效得多。因为hosts只是本地开发链路中最前面的一个环节,它能够决定“找谁”,却不能决定“谁来处理这个请求”。
喜欢这篇报道?
使用下面的功能,方便以后继续阅读和分享 MNewsTV
关于文章收藏
收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。
删除收藏请进入「我的收藏」进行管理。
分享 Facebook | X | WhatsApp | LinkedIn
捐助(Paypal): https://www.paypal.me/observeccp 订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP