Was bedeuten die Operatoren "= &" und "& =" in PHP?


Antworten:


93

$a &= $bist kurz für $a = $a & $bwas ist der bitweise-und Operator.

$a =& $bweist $ a als Referenz auf $ b zu.


11
Ich glaube nicht, dass es einen =&Operator gibt. Es ist eine Kombination aus =(Zuweisung) und unären &(Referenzierungs-) Operatoren.
Michael Krelin - Hacker

Auch auf php.net: Siehe Abschnitt "Erklärte Referenzen".
GZipp

3
@hacker: Die Verwendung eines gebräuchlichen Namens für das Sonderzeichen funktioniert normalerweise gut, z. B. "kaufmännisches Und PHP".
GZipp

1
php.net/manual/en/language.references.whatdo.php Weitere Erläuterungen zu Referenzen.
Colin Hebert

3
Nitpicking: " $a =& $bweist $ a als Referenz auf $ b zu" ist falsch, da $ a nicht auf $ b zeigt (oder umgekehrt), sondern beide auf dieselbe Stelle zeigen. Ein subtiler, aber wichtiger Unterschied.
Jürgen Thelen

39

= &

$a =& $bwird $azu einem Alias ​​für $b. Wenn der Wert oder die Referenz von $ageändert wird, ändert sich der Wert oder die Referenz von $bentsprechend.

Dies unterscheidet sich von "beide zeigen auf den gleichen Ort", wenn es um Objekte geht (ich könnte es tun $c = $d = new AnObject(), und beide Variablen würden auf den gleichen Ort zeigen; Wenn Sie jedoch ändern, wo ein Punkt liegt, ändert sich nicht, wo die anderen Punkte liegen. Das heißt, $c = nullwürde nicht machen $d = null. Im Fall der $a =& $bjedoch $a = nullwürde $b = null.

Hinweis: Offiziell werden Aliase tatsächlich als Referenzen bezeichnet. Die offizielle Terminologie ist ein bisschen falsch und sicherlich mehrdeutig, daher habe ich mich dafür entschieden, stattdessen den Begriff "Alias" zu verwenden. Dokumentation finden Sie unter php.net .

Verwendungen und Wirkungen

Bei skalaren Werten =&ähnelt dies dem Umschließen des Werts in ein Objekt, sodass Sie den Wert universell zwischen mehreren Variablen ändern können. =&Bietet bei Typen, die normalerweise als Referenz übergeben werden (Objekte), eine Referenz auf eine Referenz.

Ich neige dazu, zu verwenden, =&wenn ich mit assoziativen Arrays arbeite. Anstatt $foo['bar']['foobar']mehrmals umzuschreiben, kann ich einen Alias ​​erstellen : $foobar =& $foo['bar']['foobar']. Dies funktioniert sogar, wenn der Index noch nicht vorhanden ist. Wenn $foo['bar']['foobar']es nicht existiert, ist isset($foobar)es falsch. Es ist besser als die Verwendung einer einfachen alten Variablen, da ich den Alias ​​erstellen kann, bevor ich die Existenz des Schlüssels teste, ohne einen Fehler auszulösen.

Stellen Sie einfach sicher, unset($foobar)dass Sie den Alias deaktivieren ( ), wenn Sie fertig sind. Andernfalls überschreiben Sie, wenn Sie den Variablennamen später wiederverwenden, den Alias, auf den der Alias ​​zeigte.

Sie können Aliase auch auf andere Weise verwenden - sie sind nicht auf Zuweisungen beschränkt. Sie arbeiten mit:

  • foreach-Schleifen: Durch foreach ($a as &$b)Zuweisen von $bwird der entsprechende Wert in überschrieben $a. Deaktivieren $bSie, wenn Sie fertig sind, oder Sie werden auf seltsame Probleme stoßen !
  • Funktion / Methodenparameter: function foobar(&$a)Zuordnung zu $ainnerhalb foobarändert sich unabhängig von Variable der Anrufer als bestanden $a.
  • Funktions- / Methodenrückgabewerte: function &foobar() Was auch immer zurückgegeben wird, kann vom Aufrufer geändert werden. Dies ist nützlich, um Aliase weiterzugeben. Es ist auch leicht zu missbrauchen.
  • Arrays: $a = array(&$b) Alle Änderungen an wirken $a[0]sich jetzt aus $b, einschließlich Zuweisungen.
  • call_user_func_array: call_user_func('foobar', array(&$a)) Angenommen, es foobarwird ein einzelner Alias-Parameter verwendet, der foobarjetzt geändert werden kann $a. Auf diese Weise können Sie Funktionen / Methoden mit Alias-Parametern mit aufrufen call_user_func_array.

Beispiele

Skalare

$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

Objekte

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

& =

&=ist nicht verwandt mit =&. Es stammt aus einer Reihe von Zuweisungsoperationen. Hier sind nur einige:

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

Sehen Sie den Trend hier?

Binäre arithmetische Operatoren haben im Allgemeinen Zuweisungsgegenstücke. Nehmen wir an, @es handelt sich um einen arithmetischen Operator (nicht zum Zeitpunkt des Schreibens), der im $a @ $bAllgemeinen eine Zahl ergibt, wenn $aund $bZahlen sind. (Denken Sie: Addition, Multiplikation, Division usw.) Wie oft müssen Sie so etwas tun?

$a = $a @ $b;

Sehr oft. Scheint es nicht ein bisschen unnötig zu wiederholen $a? Viele Sprachen, einschließlich PHP, lösen dies mit einer Reihe von Zuweisungsoperatoren:

$a @= $b;

Viel einfacher und für einen Programmierer, der an diese Notation gewöhnt ist, vielleicht auf einen Blick prägnanter und beschreibender. (Ich finde es sicherlich einfacher zu lesen, da ich so daran gewöhnt bin.) Um eine Variable zu verdoppeln:

$a *= 2;

Schnell, einfach und relativ beschreibend. Einige Sprachen, einschließlich PHP, erweitern diese Funktion für ein oder zwei zusätzliche Operationen über die Arithmetik hinaus. Vor allem:

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

Sehr hilfreich.

&=fällt unter diese Zuweisungsoperatoren, weil es sich &um eine bitweise arithmetische UND-Verknüpfung handelt . In der PHP-Dokumentation sind einige andere aufgeführt (siehe oben genannten Link), die vielen Programmiersprachen gemeinsam sind.

Dies bedeutet, dass dies $a &= $bdasselbe ist wie $a = $a & $b.


3
Ihre ist die bessere Antwort aufgrund der Beispiele, die einem Neuling wie mir helfen.
Kim Stacks
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.