Docker环境下Apache的$_SERVER['request_uri']值异常求助
老哥,我太懂这种老框架踩坑的痛苦了,依赖全局变量的遗留应用移到Docker里总是会出各种奇奇怪怪的问题。结合你的情况,我帮你梳理几个最可能的原因和对应的解决办法:
1. 虚拟主机(vhost.conf)配置是重灾区
你的问题大概率出在这里,因为Apache生成$_SERVER['request_uri']完全依赖虚拟主机的正确配置。你需要检查你的vhost.conf是否包含以下关键配置:
必须设置正确的ServerName:
原服务器用的是www.test.local,那你的vhost里必须明确指定:ServerName www.test.local否则Apache无法识别请求的主机名,会默认用全局配置,导致URI解析异常。
DocumentRoot和目录权限配置:
你把./public挂载到了容器的/var/www,所以vhost里的DocumentRoot要对应上,同时开启AllowOverride All让.htaccess(如果原应用有的话)的Rewrite规则生效:DocumentRoot /var/www <Directory /var/www> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted </Directory>如果原应用依赖.htaccess里的Rewrite规则,
AllowOverride All是必须的,否则规则不生效,会导致URI被重置为"/"。RewriteBase配置:
如果原应用的Rewrite规则里用到了RewriteBase,确保在vhost里或者.htaccess里正确设置:RewriteBase /没有这个配置的话,Rewrite规则可能会错误地改写请求URI。
2. 本地Hosts映射没配置,访问方式不对
原服务器用www.test.local访问,你在本地访问Docker容器时,也必须用这个域名,而不是localhost或者IP。否则Apache收到的Host头不对,会导致$_SERVER变量解析异常:
- 打开本地机器的hosts文件(Windows是
C:\Windows\System32\drivers\etc\hosts,Linux/macOS是/etc/hosts),添加一行:127.0.0.1 www.test.local - 之后访问
http://www.test.local而不是http://localhost,这样Apache才能匹配到正确的虚拟主机配置。
3. 验证Apache Rewrite模块是否真的生效
你说已经开启了rewrite模块,但可以再确认一下,避免操作遗漏:
- 进入容器执行命令:
重启Apache后,再测试请求是否正常。docker exec -it hibrida-apache bash a2enmod rewrite service apache2 restart
4. 用测试脚本定位问题根源
如果上面的配置都检查过了还是有问题,建议在./public目录下新建一个test.php,内容如下:
<?php var_dump($_SERVER['REQUEST_URI'], $_SERVER['HTTP_HOST'], $_SERVER['SCRIPT_NAME']); ?>
然后访问http://www.test.local/test.php,看看输出的变量值:
- 如果
HTTP_HOST不是www.test.local,说明Host头没传对,问题出在访问方式或hosts配置; - 如果
REQUEST_URI还是"/",说明Apache的URI解析有问题,需要检查虚拟主机的Rewrite规则或全局Apache配置; - 如果
REQUEST_URI是正确的/test.php,那问题可能出在原应用的框架路由逻辑里(不过概率很低,因为原服务器是正常的)。
5. 检查Apache日志
进入容器查看Apache的访问日志和错误日志,能帮你快速定位问题:
docker exec -it hibrida-apache bash cat /var/log/apache2/access.log # 看请求的URI和Host头 cat /var/log/apache2/error.log # 看有没有配置错误或Rewrite报错
日志里会显示每个请求的完整信息,比如请求的URI、Host头、返回状态码等,能帮你判断是配置问题还是请求本身的问题。
内容的提问来源于stack exchange,提问作者XVirtusX

