PHP中的“=&”和“&=”运算符是什么意思?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (96)

PHP中的“=&”/“&=”运算符是什么意思?我在哪里能读到关于他们的信息?

提问于
用户回答回答于
用户回答回答于

=&

$a =& $b$a化为$b。如果$a的值或引用发生更改,$b会相应改变。

这与“两个指向同一位置”的对象不同:我可以这样做。$c = $d = new AnObject(),而这两个变量都指向同一个位置;但是,更改一个点的位置不会更改其他点。也就是说,$c = null不会使$d = null。如果$a =& $b$a = null却会使$b = null

注:从官方角度来看,别名实际上被称为引用。官方术语有点用词不当,而且肯定是模棱两可的,所以我选择了用“别名”来代替。有关文档,请参见php.net

用途和效果

用标量值,=&类似于将值包装在对象中,这样就可以在多个变量之间普遍更改值。对于通常通过引用(对象)传递的类型,=&提供对引用的引用。

我倾向于用=&当我在处理关联数组时。而不是重写$foo['bar']['foobar']多次,我可以创建一个别名:$foobar =& $foo['bar']['foobar']。如果索引还不存在的话,这些方法甚至可以工作。如果$foo['bar']['foobar']不存在,那么isset($foobar)都是假的。它比使用一个普通的旧变量更好,因为我可以在测试键是否存在之前创建别名,而不会触发错误。

请务必取消设置(unset($foobar))当你完成任务时的别名。否则,如果稍后重用变量名,则最终将覆盖别名所指向的任何内容。

你也可以用其他方式使用别名,它们不局限于作业。他们与以下方面合作:

  • foreach loops:分配给$ b将覆盖$ a中的对应值。 完成后请取消$ b设置,否则会遇到奇怪的问题!
  • function/method parameters:函数foobar(&$ a)在foobar中赋值给$ a将改变调用者作为$ a传递的任何变量。
  • function/method return values:函数和foobar()无论返回的都可以被调用者修改; 这对于传递别名很有用。 滥用也很容易。
  • arrays:$a = array(&$b) 现在对$ a [0]的任何更改都会影响$ b,包括分配。
  • call_user_func_array: call_user_func('foobar', array(&$a)) 假设foobar采用单个别名参数,foobar现在可以修改$ a。 这允许你使用call_user_func_array调用带有别名参数的函数/方法。

实例

Scalars

$original = 1;
$copy = $original;
$reference =& $original;
// All three variables == 1.

$reference = 2;
// $original == 2, $reference == 2, $copy == 1

$original = 3;
// $original == 3, $reference == 3, $copy == 1

$copy = 4;
// $original == 3, $reference == 3, $copy == 4

Objects

#!/usr/bin/env php
<?php
class Object
{
        private $properties;

        public function __construct(array $properties = array())
        {
                $this->properties = $properties;
        }

        public function __isset($key)
        {
                return isset($this->properties[$key]);
        }

        public function __unset($key)
        {
                unset($this->properties[$key]);
        }

        public function __get($key)
        {
                return isset($this->$key) ? $this->properties[$key] : null;
        }

        public function __set($key, $value)
        {
                $this->properties[$key] = $value;
        }

        public function __toString()
        {
                return print_r($this->properties, true);
        }
}

function print_vars()
{
        global $original, $ref, $refref;

        echo
                '$original: ', $original,
                '$ref: ', $ref,
                '$refref: ', $refref,
                PHP_EOL;
}

$original = new Object(array('a' => 1, 'b' => 2, 'c' => 3));
$ref = $original;
$refref =& $original;
print_vars();
/*
$original: Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
$ref: Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
$refref: Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
*/

$original->a = 'duck';
$ref->b = 'moose';
$refref->c = 'cow';
print_vars();
/*
$original: Array
(
    [a] => duck
    [b] => moose
    [c] => cow
)
$ref: Array
(
    [a] => duck
    [b] => moose
    [c] => cow
)
$refref: Array
(
    [a] => duck
    [b] => moose
    [c] => cow
)
*/

// This carries over to $refref, but not $ref.
$original = new Object(array('x' => 1, 'y' => 2, 'z' => 3));
print_vars();
/*
$original: Array
(
    [x] => 1
    [y] => 2
    [z] => 3
)
$ref: Array
(
    [a] => duck
    [b] => moose
    [c] => cow
)
$refref: Array
(
    [x] => 1
    [y] => 2
    [z] => 3
)
 */

// This does *not* carry over to $original or $ref.
$ref = new Object(array('o' => 42, 'm' => 123, 'n' => 1337));
print_vars();
/*
$original: Array
(
    [x] => 1
    [y] => 2
    [z] => 3
)
$ref: Array
(
    [o] => 42
    [m] => 123
    [n] => 1337
)
$refref: Array
(
    [x] => 1
    [y] => 2
    [z] => 3
)
*/

// This *does* carry over to $original, but not $ref.
$refref = new Object(array('alpha' => 10, 'beta' => 20, 'gamma' => 30));
print_vars();
/*
$original: Array
(
    [alpha] => 10
    [beta] => 20
    [gamma] => 30
)
$ref: Array
(
    [o] => 42
    [m] => 123
    [n] => 1337
)
$refref: Array
(
    [alpha] => 10
    [beta] => 20
    [gamma] => 30
)
*/
?>

&=

&==&...。它来自一组赋值操作。这里有几个:

  • +=
  • -=
  • *=
  • /=

看到这里的趋势了吗?

二进制算术运算符通常有赋值对应项。比如说@算运算符(不是写的时候)$a @ $b通常在以下情况下产生一个数字:$a$b是数字。(想:加法、乘法、除法等)。你需要多久做一次这样的事?

$a = $a @ $b;

经常。是不是有点没有必要重复一遍$a是吗?许多语言,包括PHP,都通过一组赋值运算符来解决这个问题:

$a @= $b;

简单得多,而且对于一个习惯了这个符号的程序员来说,一目了然,也许更简洁、更有描述性。(我当然觉得读起来更容易,因为我已经很习惯了。)。因此,要使变量加倍:

$a *= 2;

快速、简单和相对描述性的。有些语言,包括PHP,将此特性扩展到算术之外,以进行一两次额外的操作。特别是:

$a = $a . 'Appended text';
// Is the same as:
$a .= 'Appended text';

非常有用。

&=属于这些赋值运算符,因为&表示位运算。PHP文档中还列出了其他一些内容(请参阅前面提到的链接),所有这些都是许多编程语言所共有的。

这意味着$a &= $b$a = $a & $b相同。

扫码关注云+社区