$_SERVER["SERVER_NAME"]获取问题

8 篇文章 0 订阅
2 篇文章 0 订阅

在使用nginx中,当nginx里的server_name配置了多个域名的时候,发现$_SERVER["SERVER_NAME"]获取的域名是第一个而不是第二个或者第三个

既然有问题,就肯定有解决方案。。。。。。在百度主翻了N久,终于找到了需要的资料!原来:$_SERVER[“SERVER_NAME”] 返回的值是由 Nginx 的 fastcgi_param 中 SERVER_NAME 提供的,而默认的配置为:

fastcgi_param  SERVER_NAME    $server_name;

Nginx中 $server_name 变量就是上面设置的域名,只会返回第一个!

这下好办了,把上面的配置改成:

fastcgi_param  SERVER_NAME    $host;

就行了。
另外还需要在server_name配置后面加一行:

server_name_in_redirect off;

意思是 让 nginx 在处理自己内部重定向时不默认使用 server_name 设置中的第一个域名!

$_SERVER['SERVER_NAME']; 如果有域名返回域名,没有域名返回IP地址

PS:以下是网友Daze的留言,希望对本文读者有所帮助。

引用

在某些情况下(具体可参考 wiki.nginx.org),Nginx 内部重定向规则会被启动,例如,当 URL 指向一个目录并且在最后没有包含“/”时,Nginx 内部会自动的做一个 301 重定向,这时会有两种情况:
1、server_name_in_redirect on(默认),URL 重定向为: server_name 中的第一个域名 + 目录名 + /;
2、server_name_in_redirect off,URL 重定向为: 原 URL 中的域名 + 目录名 + /。

 

当你有多个域名要指向同一个虚拟主机,并且你自己写 301 重定向规则把它们合并到某一个域名时,情况就更复杂了:
首先,nginx 检查 URL,如果符合条件,就用该规则(你写的)做第一遍重定向,接着,检查新生成的 URL,如果符合内部自动重定向之条件,就用前面提到的规则再做一次重定向。


于 PHP 的 $_SERVER["SERVER_NAME"],在 nginx 中默认是由 nginx 的变量 $server_name
提供,这时它和重定向没有关系,始终是 server_name 设置中的第一个域名,但这是可以被改变的,在你的 nginx 配置中找到
fastcgi_param 部分,修改
fastcgi_param  SERVER_NAME    $server_name;

fastcgi_param  SERVER_NAME    $host;
但现在就要注意了,此时的 $_SERVER["SERVER_NAME"] 会受你写的和 nginx 自己的重定向规则所影响而变化。


在就清楚了,如果 MediaWiki 是通过 $_SERVER["SERVER_NAME"] 来自己处理 URL 的话,那么在 nginx +
php 的默认环境下,它获得的将始终是 server_name 设置中的第一个域名,所以造成了“不管通过什么域名访问 MediaWiki
首页,都会被跳转到其中的一个域名上。”,这不是 nginx 的重定向造成的,虽然默认 server_name_in_redirect 是
on,但这个指令的影响范围仅仅只是 nginx 自己内部的重定向规则,所以,当你在 nginx + php
的环境中使用多域名虚拟主机,并且你的 php 库、框架、代码大量使用 $_SERVER["SERVER_NAME"] 时,你也许应该:
1、设置 fastcgi_param  SERVER_NAME    $host;
2、设置 server_name_in_redirect off; 让 nginx 在处理自己内部重定向时不默认使用  server_name 设置中的第一个域名;
3、不要使用 nginx 的 rewrite 规则来重定向、合并多个域名。

然,后俩条是完全可选的,前提是你清楚你在做什么并且小心处理这时的  $_SERVER["SERVER_NAME"],也许更好的做法是保持
fastcgi_param  SERVER_NAME    $server_name; ,然后合理使用
$_SERVER["SERVER_NAME"] 和 $_SERVER["HTTP_HOST"]。

这个问题确实很微妙,也许我的理解还是不完全,好在还有 curl ,慢慢研究了。 🙂

P.S. nginx 0.7.x 之前的版本还有一个指令 optimize_server_names 会影响内部重定向规则。

自己测试实例:
nginx.conf配置:
第一个server:
server_name  *.myhz.com;
root  /wwwroot/myhz.com;
第二个server:
server_name  *.paidc.com;
root  /wwwroot/paidc.com;
文件内容:
/wwwroot/myhz.com/index.php的内容是:
<?
if (count(explode('a.myhz.com',$_SERVER['SERVER_NAME']))>1)
{
echo "a.myhz";
        exit();
}
else if (count(explode('b.test.com',$_SERVER['SERVER_NAME']))>1)
{
echo "b.myhz";
        exit();
}
else
echo $_SERVER['SERVER_NAME'];
?>

/wwwroot/paidc.com/index.php的内容是:
<?
if (count(explode('a.paidc.com',$_SERVER['SERVER_NAME']))>1)
{
echo "a.paidc";
        exit();
}
else if (count(explode('b.paidc.com',$_SERVER['SERVER_NAME']))>1)
{
echo "b.paidc";
        exit();
}
else
echo $_SERVER['SERVER_NAME'];
?>

访问的结果是:
a.myhz.com显示*.myhz.com
b.myhz.com显示*.myhz.com
a.paidc.com显示*.paidc.com
b.paidc.com显示*.paidc.com
知道怎么回事了吧?
就是nginx能区分出来*.myhz.com和*.paidc.com
*.myhz.com确实解析到了/wwwroot/myhz.com目录,但是php程序区分不出来a.myhz.com和b.myhz.com
*.paidc.com确实解析到了/wwwroot/paidc.com目录,但是php程序区分不出来a.paidc.com和b.paidc.com

如果将两个index.php文件中的$_SERVER['SERVER_NAME']换成 $_SERVER["HTTP_HOST"]
访问结果是:
a.myhz.com显示a.myhz
b.myhz.com显示b.myhz
a.paidc.com
显示a.paidc
b.paidc.com显示b.paidc
这么说来,就一切OK了

参考:http://ivan.xin/?p=1620

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值