PHP中的“=&”和“&=”操作符是什么意思?

时间:2022-03-10 21:05:10

What do "=&" / "&=" operators in PHP mean? Where can I read information about them?

PHP中的“=&”/“&=”操作符是什么意思?我在哪里可以读到有关他们的信息?

Searching Google doesn't help.

搜索谷歌并没有帮助。

2 个解决方案

#1


84  

$a &= $b is short for $a = $a & $b which is the bitwise-and operator.

$a &= $b的缩写为$a = $a & $b,即bitwise-and运算符。

$a =& $b assigns $a as a reference to $b.

$a = $b指定$a作为对$b的引用。

#2


35  

=&

$a =& $b turns $a into an alias for $b. If the value or reference of $a is changed, the value or reference of $b will change accordingly.

$a = $b将$a变成$b的别名。如果$a的值或引用发生改变,则$b的值或引用也会随之改变。

This differs from "both pointing to the same place" when it comes to objects: I could do $c = $d = new AnObject(), and both variables would point to the same place; however, changing where one points would not change where the other points. That is, $c = null would not make $d = null. In the case of $a =& $b, however, $a = null would make $b = null.

这与“指向同一个位置”时的对象不同:我可以做$c = $d = $ new AnObject(),两个变量都指向同一个位置;但是,改变一个点的位置不会改变另一个点的位置。也就是说,$c = null不会使$d = null。在$a =& $b的情况下,$a = null将使$b = null。

Note: Officially, aliases are actually called references. The official terminology is a bit of a misnomer and is certainly ambiguous, so I've opted to use the term "alias" instead. For documentation, see php.net.

注意:正式地,别名实际上称为引用。官方术语有点用词不当,而且肯定是含糊不清的,所以我选择使用“alias”这个词。文档,请参阅php.net。

Uses and effects

With scalar values, =& is sort of like wrapping the value in an object, so that you can change the value universally among several variables. With types that are normally passed by reference (objects), =& provides a reference to a reference.

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

I tend to use =& when I'm working with associative arrays. Rather than rewriting $foo['bar']['foobar'] several times over, I can create an alias: $foobar =& $foo['bar']['foobar']. These even works if the index doesn't exist yet. If $foo['bar']['foobar'] doesn't exist, then isset($foobar) will be false. It's better than using a plain old variable, because I can create the alias before testing for the existence of the key without triggering an error.

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

Just be sure to unset (unset($foobar)) the alias when you're done. Otherwise, if you reuse the variable name later, you'll end up overwriting whatever the alias was pointing to.

当您完成时,请确保未设置(unset($foobar))别名。否则,如果稍后重用变量名,您将最终覆盖别名指向的任何内容。

You can use aliases in other ways, too--they're not limited to assignments. They work with:

你也可以用其他方式使用别名——它们不局限于作业。他们的工作:

  • foreach loops: foreach ($a as &$b) Assigning to $b will overwrite the corresponding value in $a. Unset $b when you're done, or you'll run into weird problems!
  • foreach循环:分配给$b的foreach ($a和$b)将覆盖$a中相应的值。当你完成时未设置$b,否则你会遇到奇怪的问题!
  • function/method parameters: function foobar(&$a) Assigning to $a within foobar will change whatever variable the caller passed as $a.
  • 函数/方法参数:函数foobar(&$a)在foobar中分配给$a将改变调用者作为$a传递的任何变量。
  • function/method return values: function &foobar() Whatever is returned can be modified by the caller; this is useful for passing around aliases. It's also easy to abuse.
  • 函数/方法返回值:函数&foobar()返回的任何内容都可以被调用者修改;这对于传递别名非常有用。这也很容易被滥用。
  • arrays: $a = array(&$b) Any changes to $a[0] will now affect $b, including assignments.
  • 数组:$a = array(&$b)对$a[0]的任何更改现在都会影响$b,包括赋值。
  • call_user_func_array: call_user_func('foobar', array(&$a)) Assuming foobar takes a single alias parameter, foobar can now modify $a. This allows you to call functions/methods with alias parameters using call_user_func_array.
  • call_user_func_array: call_user_func('foobar', array(&$a))假设foobar接受一个别名参数,那么foobar现在可以修改$a。这允许您使用call_user_func_array调用具有别名参数的函数/方法。

Examples

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
)
*/
?>

&=

&= is unrelated to =&. It comes from a set of assignment operations. Here's just a few:

与=无关。它来自一组赋值操作。这里有几个:

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

See the trend here?

看到这一趋势吗?

Binary arithmetic operators generally have assignment counterparts. Let's say @ were an arithmetic operator (it's not as of writing) such that $a @ $b generally yields a number when $a and $b are numbers. (Think: Addition, multiplication, division, etc.) How often do you need to do something like this?

二进制算术运算符一般都有赋值对应项。假设@是一个算术运算符(不像写的那样),当$a和$b是数字时,$a @ $b通常会产生一个数字。(想想:加法、乘法、除法等)你多久需要做一次这样的事情?

$a = $a @ $b;

Pretty often. Doesn't it seem a bit unnecessary to repeat $a? Many languages, including PHP, solve this with an array of assignment operators:

很经常。难道不需要重复a美元吗?许多语言,包括PHP,都通过一系列赋值操作符来解决这个问题:

$a @= $b;

Much simpler, and to a programmer accustomed to this notation, perhaps more concise and descriptive at a glance. (I certainly find it easier to read, since I'm so used to it.) So to double a variable:

更简单,对于一个习惯了这种符号的程序员来说,可能更简洁和描述性更强。(我当然觉得它更容易阅读,因为我已经习惯了。)让一个变量加倍

$a *= 2;

Quick, easy, and relatively descriptive. Some languages, including PHP, extend this feature beyond arithmetic for an extra operation or two. Notably:

快速,简单,和相对描述性。包括PHP在内的一些语言将此功能扩展到算术之外,以进行额外的操作。值得注意的是:

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

Very useful.

非常有用的。

&= falls among these assignment operators, because & represents a bitwise arithmetic AND operation. There are a few others listed in the PHP documentation (see aforementioned link), all of which are common to many programming languages.

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

This means that $a &= $b is the same as $a = $a & $b.

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

#1


84  

$a &= $b is short for $a = $a & $b which is the bitwise-and operator.

$a &= $b的缩写为$a = $a & $b,即bitwise-and运算符。

$a =& $b assigns $a as a reference to $b.

$a = $b指定$a作为对$b的引用。

#2


35  

=&

$a =& $b turns $a into an alias for $b. If the value or reference of $a is changed, the value or reference of $b will change accordingly.

$a = $b将$a变成$b的别名。如果$a的值或引用发生改变,则$b的值或引用也会随之改变。

This differs from "both pointing to the same place" when it comes to objects: I could do $c = $d = new AnObject(), and both variables would point to the same place; however, changing where one points would not change where the other points. That is, $c = null would not make $d = null. In the case of $a =& $b, however, $a = null would make $b = null.

这与“指向同一个位置”时的对象不同:我可以做$c = $d = $ new AnObject(),两个变量都指向同一个位置;但是,改变一个点的位置不会改变另一个点的位置。也就是说,$c = null不会使$d = null。在$a =& $b的情况下,$a = null将使$b = null。

Note: Officially, aliases are actually called references. The official terminology is a bit of a misnomer and is certainly ambiguous, so I've opted to use the term "alias" instead. For documentation, see php.net.

注意:正式地,别名实际上称为引用。官方术语有点用词不当,而且肯定是含糊不清的,所以我选择使用“alias”这个词。文档,请参阅php.net。

Uses and effects

With scalar values, =& is sort of like wrapping the value in an object, so that you can change the value universally among several variables. With types that are normally passed by reference (objects), =& provides a reference to a reference.

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

I tend to use =& when I'm working with associative arrays. Rather than rewriting $foo['bar']['foobar'] several times over, I can create an alias: $foobar =& $foo['bar']['foobar']. These even works if the index doesn't exist yet. If $foo['bar']['foobar'] doesn't exist, then isset($foobar) will be false. It's better than using a plain old variable, because I can create the alias before testing for the existence of the key without triggering an error.

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

Just be sure to unset (unset($foobar)) the alias when you're done. Otherwise, if you reuse the variable name later, you'll end up overwriting whatever the alias was pointing to.

当您完成时,请确保未设置(unset($foobar))别名。否则,如果稍后重用变量名,您将最终覆盖别名指向的任何内容。

You can use aliases in other ways, too--they're not limited to assignments. They work with:

你也可以用其他方式使用别名——它们不局限于作业。他们的工作:

  • foreach loops: foreach ($a as &$b) Assigning to $b will overwrite the corresponding value in $a. Unset $b when you're done, or you'll run into weird problems!
  • foreach循环:分配给$b的foreach ($a和$b)将覆盖$a中相应的值。当你完成时未设置$b,否则你会遇到奇怪的问题!
  • function/method parameters: function foobar(&$a) Assigning to $a within foobar will change whatever variable the caller passed as $a.
  • 函数/方法参数:函数foobar(&$a)在foobar中分配给$a将改变调用者作为$a传递的任何变量。
  • function/method return values: function &foobar() Whatever is returned can be modified by the caller; this is useful for passing around aliases. It's also easy to abuse.
  • 函数/方法返回值:函数&foobar()返回的任何内容都可以被调用者修改;这对于传递别名非常有用。这也很容易被滥用。
  • arrays: $a = array(&$b) Any changes to $a[0] will now affect $b, including assignments.
  • 数组:$a = array(&$b)对$a[0]的任何更改现在都会影响$b,包括赋值。
  • call_user_func_array: call_user_func('foobar', array(&$a)) Assuming foobar takes a single alias parameter, foobar can now modify $a. This allows you to call functions/methods with alias parameters using call_user_func_array.
  • call_user_func_array: call_user_func('foobar', array(&$a))假设foobar接受一个别名参数,那么foobar现在可以修改$a。这允许您使用call_user_func_array调用具有别名参数的函数/方法。

Examples

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
)
*/
?>

&=

&= is unrelated to =&. It comes from a set of assignment operations. Here's just a few:

与=无关。它来自一组赋值操作。这里有几个:

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

See the trend here?

看到这一趋势吗?

Binary arithmetic operators generally have assignment counterparts. Let's say @ were an arithmetic operator (it's not as of writing) such that $a @ $b generally yields a number when $a and $b are numbers. (Think: Addition, multiplication, division, etc.) How often do you need to do something like this?

二进制算术运算符一般都有赋值对应项。假设@是一个算术运算符(不像写的那样),当$a和$b是数字时,$a @ $b通常会产生一个数字。(想想:加法、乘法、除法等)你多久需要做一次这样的事情?

$a = $a @ $b;

Pretty often. Doesn't it seem a bit unnecessary to repeat $a? Many languages, including PHP, solve this with an array of assignment operators:

很经常。难道不需要重复a美元吗?许多语言,包括PHP,都通过一系列赋值操作符来解决这个问题:

$a @= $b;

Much simpler, and to a programmer accustomed to this notation, perhaps more concise and descriptive at a glance. (I certainly find it easier to read, since I'm so used to it.) So to double a variable:

更简单,对于一个习惯了这种符号的程序员来说,可能更简洁和描述性更强。(我当然觉得它更容易阅读,因为我已经习惯了。)让一个变量加倍

$a *= 2;

Quick, easy, and relatively descriptive. Some languages, including PHP, extend this feature beyond arithmetic for an extra operation or two. Notably:

快速,简单,和相对描述性。包括PHP在内的一些语言将此功能扩展到算术之外,以进行额外的操作。值得注意的是:

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

Very useful.

非常有用的。

&= falls among these assignment operators, because & represents a bitwise arithmetic AND operation. There are a few others listed in the PHP documentation (see aforementioned link), all of which are common to many programming languages.

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

This means that $a &= $b is the same as $a = $a & $b.

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