3 Stimmen

PHP Array Referenz Verwirrung

Mit diesem Code:

$a[1]=1;
$a[2]=& $a[1];

$b=$a;
$b[2]=7;

print_r($a);

Ich hatte erwartet, dass die Ausgabe 1 denn $a wird nicht durch Verweis auf $b ( $a = & $b ), aber es ergibt sich folgendes Bild 7 . Warum?

4voto

Matthew Flaschen Punkte 266507

Sie kopieren das Array nach Wert, aber die Elemente des Quellarrays sind Referenzen. Diese Referenzen werden nur oberflächlich in das Ziel kopiert.

php > var_dump($a);
array(2) {
  [1]=>
  &int(1)
  [2]=>
  &int(1)
}
php > $b=$a;
php > var_dump($b);
array(2) {
  [1]=>
  &int(1)
  [2]=>
  &int(1)
}

Hier ein Beispiel, bei dem das Array per Referenz kopiert wird:

php > $c[1] = 1;
php > $c[2] =& $c[1];
php > var_dump($c);
array(2) {         
  [1]=>            
  &int(1)
  [2]=>
  &int(1)
}
php > $d =& $c;
php > var_dump($d);
array(2) {
  [1]=>
  &int(1)
  [2]=>
  &int(1)
}
php > $d = array(3,4,5);
php > var_dump($c);
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(4)
  [2]=>
  int(5)
}
php > var_dump($d);
array(3) {
  [0]=>
  int(3)
  [1]=>
  int(4)
  [2]=>
  int(5)
}

Wie Sie sehen können, ist die Array-Variable (nicht die Elemente) selbst ein Verweis, so dass das Ändern von $d betrifft $c . Neu zuweisen $b selbst hat keine Auswirkungen auf $a .

3voto

StasM Punkte 10085

So funktioniert das mit den Referenzen. Was wollen Sie damit sagen, wenn Sie $a[2]=& $a[1]; ist, dass beide Elemente von $a nun dieselbe Variable enthalten. Wenn Sie $b = $a eingeben, sind $b und $a unterschiedliche Variablen, aber alle 4 Elemente in ihnen zeigen auf dieselbe Variable! Versuchen Sie Folgendes $b[3] = 7 und sehen, dass es nicht nach $a kopiert wird - weil $b und $a unterschiedlich sind, $b[2] und $a[2] aber nicht!

Die Referenzen sind etwas unübersichtlich, sorry. Vermeiden Sie es, sie zu verwenden, wenn Sie nicht müssen.

2 Stimmen

Die Erklärung ist zwar gut, der Ratschlag, die Verwendung von Verweisen zu vermeiden, jedoch nicht.

0 Stimmen

Danke, ich finde Ihre Erklärung leichter zu verstehen, aber auch danke an Matthew.

0 Stimmen

@stillstanding: Wenn Sie sie verwenden müssen, verwenden Sie sie auf jeden Fall. Aber in vielen Fällen ist es nicht notwendig - z.B. habe ich php4-Code gesehen, der refs mit Objekten verwendet, oder Arrays durch refs "für die Geschwindigkeit" übergibt, etc. Das sollte nicht gemacht werden. Natürlich gibt es legitime Verwendungen von refs.

0voto

llamerr Punkte 2868

Das hilft mir zu verstehen, was Referenzen sind:

http://www.php.net/manual/en/features.gc.refcounting-basics.php

http://books.google.com/books? id=e7D-mITABmEC&pg=PT171&lpg=PT171&dq=php+object+zval&source=bl&ots=oawmzMtsXt&sig=mMSuVKsk6L3JWuEikJN8j7dQfRs&hl=ru&ei=JmDWTOraI4TNswaDt- jkCA&sa=X&oi=book_result&ct=result&resnum=10&ved=0CEcQ6AEwCQ#v=onepage&q=php%20object%20zval&f=false

Und die Fehlersuche mit xdebug in interessanten Fällen hilft auch

Sie können zum Beispiel private Grundstücke "meiden":

class c{
    private $a = 42;
    function &a(){
        return $this->a;
    }
    function print\_a(){
        echo $this->a;
    }
}
$c = new c;
$d = &$c->a();
echo $d;
$d = 2;
$c->print\_a();

oder per Verweis an Funktionen übergeben, wenn Sie es nicht deklariert haben:

function f1(&$s) {
    $s++;
}
function f2($s) {
    $s--;
}
$s1 = 1;
$s2 = 3;
f1($s1);
f2(&$s2);
echo $s1.$s2;

foreach kann auch pass-by-reference verwenden

$a = array(1,2,3); foreach ( $a as $key => &$value ) { $wert = 1; } $wert = 2;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X