在PHP中给自己赋值有什么效果?
what is the effect of assign a variable to itself in PHP?
我正在研究 HTTP-Tunnel Project 中的一段代码,我在文件 lib.php
的第 315 行遇到了这个有线变量赋值
if ($publicname) $sysn=$sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
我不明白为什么变量 $sysn 被分配给它自己?
代码行所在的函数:
function getmyip ($publicname) {
// try to get the name wih multiple methods in this order:
// $publicname: SERVER_ADDR, SERVER_NAME, php_uname, uname, hostname, own script
// !$publicname: php_uname, uname, hostname, own script, SERVER_ADDR, SERVER_NAME,
$sysn="";
if ($publicname) $sysn=$sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn)) $sysn=php_uname("n");
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn)) $sysn=`uname -n`;
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn)) $sysn=`hostname`;
if ($_SERVER["HTTP_HOST"]!="127.0.0.1" && $_SERVER["HTTP_HOST"]!="locahost") {
$sysurl="http://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"]."?a=ip";
$sysn=file_get_contents($sysurl);
$sysn=preg_replace("/\r|\n/","",$sysn);
}
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn))
$sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
if (!$sysn) $sysn=$_SERVER["HTTP_HOST"];
return gethostbyname($sysn);
}
它什么也做不了。这与.
if ($publicname) $sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
可能是打字错误?还是什么?
在PHP中,assignment运算符具有右结合性。意思是,一个变量被分配给另一个被分配给某物的变量,最终只会将这些变量分配给最右边的值。由于变量是相同的,所以逻辑没有改变的是$synsn
之一被删除。
这是糟糕的代码,您不应该使用它,但它本质上是一个写得不好的 NULL 合并。 NULL 合并归结为:
if( is_null($bar) ) {
$foo = 'some default or alternate value';
} else {
$foo = $bar;
}
为了更好的可读性:
$sysn = (
($sysn = $_SERVER["SERVER_ADDR"]) ?
$_SERVER["SERVER_ADDR"] :
$_SERVER["SERVER_NAME"]
);
请注意,评估赋值操作的结果 returns 赋值操作是 右关联 因此它们从右链接到离开了。
一个更简洁的例子:
$foo = ( $foo = $bar ) ? $bar : 'bar was unset';
// ^- NULL, which is false-y
var_dump($foo);
$bar = 'I am bar';
$foo = ( $foo = $bar ) ? $bar : 'bar was unset';
// ^- string, which is truth-y
var_dump($foo);
输出:
Notice: Undefined variable: bar in /in/q2A4n on line 1
string(13) "bar was unset"
string(8) "I am bar"
不应忽略通知,它们表明您做错了什么。还没有错到停止执行,但错到可能在某处导致问题。
如果这是一个有标准并且能够感到羞耻的人写的,那将是:
$sysn = (
( isset($_SERVER["SERVER_ADDR"]) ) ?
$_SERVER["SERVER_ADDR"] :
$_SERVER["SERVER_NAME"]
);
或在 PHP>=7 中使用 NULL coalesce operator:
$sysn = $_SERVER["SERVER_ADDR"] ?? $_SERVER["SERVER_NAME"]
我正在研究 HTTP-Tunnel Project 中的一段代码,我在文件 lib.php
的第 315 行遇到了这个有线变量赋值if ($publicname) $sysn=$sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
我不明白为什么变量 $sysn 被分配给它自己?
代码行所在的函数:
function getmyip ($publicname) {
// try to get the name wih multiple methods in this order:
// $publicname: SERVER_ADDR, SERVER_NAME, php_uname, uname, hostname, own script
// !$publicname: php_uname, uname, hostname, own script, SERVER_ADDR, SERVER_NAME,
$sysn="";
if ($publicname) $sysn=$sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn)) $sysn=php_uname("n");
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn)) $sysn=`uname -n`;
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn)) $sysn=`hostname`;
if ($_SERVER["HTTP_HOST"]!="127.0.0.1" && $_SERVER["HTTP_HOST"]!="locahost") {
$sysurl="http://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"]."?a=ip";
$sysn=file_get_contents($sysurl);
$sysn=preg_replace("/\r|\n/","",$sysn);
}
if (!$sysn || $sysn=="127.0.0.1" || $sysn=="localhost" || preg_match("/\s/",$sysn))
$sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
if (!$sysn) $sysn=$_SERVER["HTTP_HOST"];
return gethostbyname($sysn);
}
它什么也做不了。这与.
if ($publicname) $sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];
可能是打字错误?还是什么?
在PHP中,assignment运算符具有右结合性。意思是,一个变量被分配给另一个被分配给某物的变量,最终只会将这些变量分配给最右边的值。由于变量是相同的,所以逻辑没有改变的是$synsn
之一被删除。
这是糟糕的代码,您不应该使用它,但它本质上是一个写得不好的 NULL 合并。 NULL 合并归结为:
if( is_null($bar) ) {
$foo = 'some default or alternate value';
} else {
$foo = $bar;
}
为了更好的可读性:
$sysn = (
($sysn = $_SERVER["SERVER_ADDR"]) ?
$_SERVER["SERVER_ADDR"] :
$_SERVER["SERVER_NAME"]
);
请注意,评估赋值操作的结果 returns 赋值操作是 右关联 因此它们从右链接到离开了。
一个更简洁的例子:
$foo = ( $foo = $bar ) ? $bar : 'bar was unset';
// ^- NULL, which is false-y
var_dump($foo);
$bar = 'I am bar';
$foo = ( $foo = $bar ) ? $bar : 'bar was unset';
// ^- string, which is truth-y
var_dump($foo);
输出:
Notice: Undefined variable: bar in /in/q2A4n on line 1
string(13) "bar was unset"
string(8) "I am bar"
不应忽略通知,它们表明您做错了什么。还没有错到停止执行,但错到可能在某处导致问题。
如果这是一个有标准并且能够感到羞耻的人写的,那将是:
$sysn = (
( isset($_SERVER["SERVER_ADDR"]) ) ?
$_SERVER["SERVER_ADDR"] :
$_SERVER["SERVER_NAME"]
);
或在 PHP>=7 中使用 NULL coalesce operator:
$sysn = $_SERVER["SERVER_ADDR"] ?? $_SERVER["SERVER_NAME"]