【问题标题】:what is the effect of assign a variable to itself in PHP?在PHP中将变量分配给自身的效果是什么?
【发布时间】:2018-06-04 22:24:54
【问题描述】:

我正在研究来自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);
}

【问题讨论】:

  • 我猜错了,因为它什么也没做
  • 这对我来说看起来很奇怪,但我确实注意到赋值实际上是三元语句的条件语句。我自己也无法破译这个,但我认为这是一个很好的参考框架。
  • 我也将其称为三元语句。我猜第二个等号应该是双等号,所以== 而不是=...
  • @arkascha 我不这么认为,因为 $sysn 变量的类型是 String 并且已通过 gethostbyname($sysn); 确认;
  • @smith 我想是这样,但它可能是可变阴影吗?

标签: php variable-assignment


【解决方案1】:

这是一个糟糕的代码,你不应该使用它,但它本质上是一个写得很糟糕的 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"] 
);

请注意,评估赋值操作的结果会返回被赋值的值,并且赋值操作是右关联的,因此它们是从右到左链接的。

一个更简洁的例子:

$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"]

【讨论】:

  • 哇,这是我见过的最完美的答案,非常感谢。但请重新检查问题中函数实现代码中的第 16 行(或 lib.php 中的 325)。
【解决方案2】:

它不会做任何事情。这将是相同的。

if ($publicname) $sysn=$_SERVER["SERVER_ADDR"]?$_SERVER["SERVER_ADDR"]:$_SERVER["SERVER_NAME"];

可能是错字?还是什么?

【讨论】:

    【解决方案3】:

    在 PHP 中,assignment 运算符具有右关联性。意思是,分配给另一个变量的变量正在分配给某物,最终只会将这些变量分配给最右边的值。由于变量相同,逻辑不变的是$synsn之一被删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-03
      • 2014-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-10
      • 2022-10-05
      • 2023-03-26
      相关资源
      最近更新 更多