Что означают операторы «= &» и «& =» в PHP?

Что означают операторы «= &» / «& =» в PHP? Где я могу прочитать информацию о них?

Поиск Google не помогает.

Solutions Collecting From Web of "Что означают операторы «= &» и «& =» в PHP?"

$a &= $b является коротким для $a = $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) будет false. Это лучше, чем использование простой старой переменной, потому что я могу создать псевдоним перед тестированием на наличие ключа без возникновения ошибки.

Просто обязательно отмените ( unset($foobar) ) псевдоним, когда вы закончите. В противном случае, если вы повторно используете имя переменной позже, вы в конечном итоге перепишете все, что указывал псевдоним.

Вы также можете использовать псевдонимы другими способами – они не ограничены назначениями. Они работают с:

  • foreach: foreach ($a as &$b) Присвоение $b будет перезаписывать соответствующее значение в $a . Unset $b когда вы закончите, или у вас возникнут странные проблемы!
  • Параметры функции / метода: function foobar(&$a) Присвоение переменной $a внутри foobar изменяет любую переменную, передаваемую вызывающим пользователем как $a .
  • function / method return values: function &foobar() Все, что возвращается, может быть изменено вызывающим; это полезно для обхода псевдонимов. Это также легко злоупотреблять.
  • массивы: $a = array(&$b) Любые изменения в $a[0] теперь будут влиять на $b , включая присвоения.
  • call_user_func_array: 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 ) */ ?> не #!/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 .