【问题标题】:PHP "&" operatorPHP "&" 运算符
【发布时间】:2011-01-13 16:11:11
【问题描述】:

我不是 PHP 程序员(但知道其他语言),我正在尝试理解一个用 PHP (5.1.6) 完成的网页,以便进行一些更改。

页面有如下代码(简体):

$db_hosts = array();
$sql = 'SELECT h.hostid, h.host FROM hosts h ';

$db_items = DBselect($sql);

while($db_item = DBfetch($db_items)){
    $name = $db_item['host'];
    $db_host = &$db_hosts[$db_item['hostid']];
}

我试图理解最后一行,$db_host = &$db_hosts[$db_item['hostid']];

似乎是在创建一个新变量$db_host,并在其中放入一些东西,但我不明白&$db_hosts

我很怀疑,因为据我所知,$db_hosts 是一个空数组。

我找到了thisthis,但我不太确定,因为在这些链接中,运算符是“=&”,而在代码中,运算符是附加到变量“= &$ db_hosts”(在 = 和 & 之间有一个空格)。

由于我尝试修改它并没有成功,我认为最好寻求帮助......

【问题讨论】:

    标签: php


    【解决方案1】:

    & 用于获取对变量的引用。它类似于 C++ 等其他语言中的引用,但有一些显着差异。请参阅PHP Manual's section on references

    【讨论】:

    • 你对@符号的看法。
    • @Michael Brooks:是的,对不起,我回答得太快了。我已经更正了我的答案。
    • 虽然乍一看似乎合理,但这是一个非常具有误导性的答案:& 没有“获取”引用,因为引用本身不存在(例如,C指针会)。相反,最好将=& 视为将两个变量联系在一起的运算符,而将相关语法(例如function foo(&$bar))视为编写该赋值的方式。
    【解决方案2】:

    这些是引用,它们类似于 C 或 C++ 中的“指针”。

    更多信息在PHP manual

    在这种情况下,由于$db_hosts 为空,构造$db_hosts[$db_item['hostid']] 将在$db_item['hostid'] 的索引上创建一个包含空项的新数组并返回该项的引用,使$db_host 充当“别名” ' 对于 $db_hosts[$db_item['hostid']] 当前是什么。

    【讨论】:

    【解决方案3】:

    & 用作参考。看看有哪些参考资料 http://php.net/manual/en/language.references.php:

    PHP 中的引用是一种 访问相同的变量内容 不同的名称。他们不像C 指针;例如,你不能 使用它们执行指针运算, 它们不是实际的内存地址, 等等。

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        将该变量指定为引用,这样如果稍后更改 $db_host,$db_hosts 数组中的相应条目也会更改,反之亦然。

        我在 PHP 中看到了相当多的毫无意义的引用,货物崇拜风格。也许需要这个,也许不需要 - 你必须查看程序的其余部分。

        【讨论】:

          【解决方案6】:

          & 在 PHP 中以多种方式用于表示引用 (see this manual section),但将其视为本身就是一个运算符会产生误导。这就是为什么有些人更喜欢写成$foo =& $bar 而不是$foo = &$bar - 它的意思是一样的,但强调“reference-y-ness”是赋值的属性,而不是变量的属性。

          在某些编程语言中,例如 C 或 C++,您可以“获取对”特定变量的引用;结果值可以作为一个不同的实体传递,然后“取消引用”以找出它指向的位置。这不是 PHP 引用。

          相反,所有 PHP 变量实际上是对称为zval 的内部类型的引用。你不能在 PHP 中直接操作zvals,也不能做额外的间接层——每个变量都是对zval 的引用,仅此而已。 (请参阅警告:下面的对象。)

          引用赋值 ($foo =& $bar)、引用传递 (function foo(&$bar) { ... }) 或引用返回 (return &$foo) 的作用是告诉 PHP 你想要两个变量指向同一个zval。请注意,您并没有将一个变量指向另一个变量——它们都同样“真实”,并且在其中一个上调用 unset() 将使另一个完全不变。

          警告:对象

          由于 PHP5 对象“总是通过引用传递”,因此经常被误导。事实上,它们有一个额外的间接层,其中zval 本身就是一个指向特定对象的指针。这给了我们三个可以引用的不同的东西:变量,它指向的zval,以及它指向的object

          // Create an object, and point three variables at it in different ways:
          $foo = new stdClass;
          $bar_by_value = $foo;
          $bar_by_ref =& $foo;
          
          // Change the object: updates the object shared by all three variables
          $foo->value = 42;
          // Change the value (zval) of $foo: will update $bar_by_ref, 
          //   but $bar_by_value still points at the original object
          $foo = 42; 
          // Change the variable itself: will never affect $bar_by_value or $bar_by_ref
          unset($foo);
          

          【讨论】:

          • 感谢您的解释,但如果您要更改 $bar_by_ref->value = 43; 会更新 $bar_by_value$foo 吗?以我有一个浮点数组为例,我想四舍五入。像foreach($float as& $f) $f = ROUND($f, 1); 这样的电话可以工作吗?并将所有 $float 值更新为四舍五入的数字?
          • @Jaquarh 简而言之,是的,是的,尽管这两个问题非常不同。首先,想想$bar_by_ref 指向的对象是什么;是和$foo 一样,还是在某处创建了一个新对象? foreach循环与写$f =& $float[0]; $f = round($f, 1); $f =& $float[1]; $f = round($f, 1);等基本相同,所以遵循正常的引用规则。
          • 我现在明白这个概念了!老实说,阅读 zvals 很有趣,因为它表明它们可以像 foreach 那样被操纵来更改数组而不是重新创建一个全新的数组。感谢您抽出宝贵时间回复我的评论!
          【解决方案7】:

          问题

          “&”在 PHP 中是什么意思?

          PHP“&”运算符

          一旦我们习惯了它会让生活更轻松..(仔细查看下面的示例)

          & 通常检查在 $a 和 $b 中设置的位是否已设置。

          你有没有注意到这些调用是如何工作的?

             error_reporting(E_ERROR | E_WARNING | E_PARSE);
              error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
              error_reporting(E_ALL & ~E_NOTICE);
              error_reporting(E_ALL);
          

          所以在这一切的背后是位运算符和位的游戏。

          其中一个有用的例子是像下面给出的简单配置,因此单个整数字段可以为您存储数千个组合。

          大多数人已经阅读过文档,但并未了解这些位运算符的实际用例。

          示例 这对日常的 php 生活非常有用

          <?php
          
          class Config {
          
              // our constants must be 1,2,4,8,16,32,64 ....so on
              const TYPE_CAT=1;
              const TYPE_DOG=2;
              const TYPE_LION=4;
              const TYPE_RAT=8;
              const TYPE_BIRD=16;
              const TYPE_ALL=31;
          
              private $config;
          
              public function __construct($config){
                  $this->config=$config;
          
                  if($this->is(Config::TYPE_CAT)){
                      echo 'cat ';
                  }
                  if($this->is(Config::TYPE_DOG)){
                      echo 'dog ';
                  }
                  if($this->is(Config::TYPE_RAT)){
                      echo 'rat ';
                  }
                  if($this->is(Config::TYPE_LION)){
                      echo 'lion ';
                  }
                  if($this->is(Config::TYPE_BIRD)){
                      echo 'bird ';
                  }
                  echo "\n";
              }
          
              private function is($value){
                  return $this->config & $value;
              }
          }
          
          new Config(Config::TYPE_ALL);
          // cat dog rat lion bird
          new Config(Config::TYPE_BIRD);
          //bird
          new Config(Config::TYPE_BIRD | Config::TYPE_DOG);
          //dog bird
          new Config(Config::TYPE_ALL & ~Config::TYPE_DOG & ~Config::TYPE_CAT);
          //rat lion bird
          

          【讨论】:

          • 这是一个很好的例子......一个完全不同的运算符。它恰好也拼写为&amp;,但问题中的运算符是引用赋值,与按位运算无关。
          • 太好了,您可以随时为您喜欢的任何内容投票,这可能对您和其他人有帮助。
          • 为什么是TYPE_ALL=31?那不应该是 32 岁吗?
          • 31 表示包含所有,32 本身是单个值,而 31 表示合并所有
          • 因为 1+2+4+8+16 = 31
          【解决方案8】:

          下面是一个简单的例子来解释PHP&amp;操作符的含义:

          <?php
          
          $x = "Hello";
          
          $y = &$x;
          echo "Value of x : " . $x . "\n";
          echo "Value of y : " . $y . "\n";
          
          $y = "Hi"; // Since $y is alias or reference of the variable $x, so value of $x will also be changed, see below:
          
          echo "Value of x : " . $x . "\n";
          echo "Value of y : " . $y . "\n";
          

          以上代码输出如下:

          Value of x : Hello
          Value of y : Hello
          Value of x : Hi
          Value of y : Hi
          

          从上面的例子可以看出,它是变量的引用。

          来自官方文档:What References Are

          PHP 中的引用是一种通过不同名称访问相同变量内容的方法。它们不像 C 指针;例如,您不能使用它们执行指针运算,它们不是实际的内存地址,等等。有关更多信息,请参阅什么不是参考。相反,它们是符号表别名。注意在PHP中,变量名和变量内容是不同的,所以同样的内容可以有不同的名字。最接近的类比是 Unix 文件名和文件 - 变量名是目录条目,而变量内容是文件本身。引用可以比作​​ Unix 文件系统中的硬链接。

          【讨论】:

            猜你喜欢
            • 2011-05-28
            • 1970-01-01
            • 2010-12-31
            • 2011-08-21
            • 1970-01-01
            • 2015-02-20
            • 2013-04-03
            • 2010-09-19
            相关资源
            最近更新 更多