PHP中的“ =&” /“&=”运算符是什么意思?在哪里可以阅读有关它们的信息?
搜索Google没有帮助。
Answers:
=&
操作员。它是=
(赋值)运算&
符和一元(引用)运算符的组合。
$a =& $b
将$ a分配为对$ b的引用”是错误的,因为$ a并不指向$ b(反之亦然),但是两者都指向同一位置。细微但重要的区别。
$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 ($a as &$b)
分配给$b
会覆盖中的相应值$a
。完成后取消设置$b
,否则会遇到奇怪的问题!function foobar(&$a)
在$a
内部分配foobar
将更改调用方以形式传递的任何变量$a
。function &foobar()
无论返回什么,调用方都可以修改;这对于传递别名很有用。这也很容易滥用。$a = array(&$b)
任何更改$a[0]
现在都会影响$b
,包括分配。call_user_func('foobar', array(&$a))
假设foobar
有一个别名参数,foobar
现在可以进行修改$a
。这使您可以使用使用别名参数调用函数/方法call_user_func_array
。$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
#!/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';
很有用。
&=
落在这些赋值运算符之内,因为它&
表示按位算术AND运算。PHP文档中还列出了其他一些内容(请参见前面的链接),这些都是许多编程语言所共有的。
这意味着$a &= $b
与相同$a = $a & $b
。
=&
不是“组合运算符”。这是一个解释为什么您永远不要写的帖子=&
:stackoverflow.com/a/63914758/2943403