dedlfix: Session - Größenbeschränkungen?

Beitrag lesen

echo $begrüßung;

PHP legt bei einer Kopie nicht sofort die Daten doppelt an. Erst wenn die Werte in den Variablen "auseinanderlaufen" wird kopiert.

Für welche Datentypen in welchen Situationen trifft das zu? Sind außer den Arrays auch andere davon betroffen?

PHP macht das für alle Variablen unabhängig von ihrem Typ ($_SESSION und $HTTP_SESSION_VARS scheinen eine und die wohl auch die einzige Ausnahme zu sein).

Versteckt auf der Handbuchseite zu debug_zval_dump() findet sich ein Verweis auf ein PDF-Dokument auf Derik Rethans' Seiten: PHP References Article, das den internen Ablauf beschreibt.

Mit debug_zval_dump() kann man auch das Verhalten verfolgen:

$a = 42;
  echo 'a: '; debug_zval_dump($a);

Ausgabe ist

a: long(42) refcount(2)

Der refcount ist aufgrund des Funktionsaufruf von debug_zval_dump() und der damit verbundenen (Nicht-)Kopie in die debug_zval_dump()-interne Parameter-Variable eins höher als das erwartete 1. Es gibt also zwei Verweise auf einen zval, PHPs Variablencontainer.

Ich füge zwei Variablen als direkte und indirekte Kopie von $a hinzu:

$b = $a;
  $c = $b;
  echo 'a: '; debug_zval_dump($a);
  echo 'b: '; debug_zval_dump($b);
  echo 'c: '; debug_zval_dump($c);

und sehe einen um 2 erhöhten refcount von 4 für alle drei Variablen:

a: long(42) refcount(4)
  b: long(42) refcount(4)
  c: long(42) refcount(4)

Ändere ich die Werte von $b und $c

$b = 23;
  echo 'a: '; debug_zval_dump($a);
  echo 'b: '; debug_zval_dump($b);
  echo 'c: '; debug_zval_dump($c);

$c = 'foo';
  echo 'a: '; debug_zval_dump($a);
  echo 'b: '; debug_zval_dump($b);
  echo 'c: '; debug_zval_dump($c);

verringert sich auch der refcount:

a: long(42) refcount(3)
  b: long(23) refcount(2)
  c: long(42) refcount(3)

a: long(42) refcount(2)
  b: long(23) refcount(2)
  c: string(3) "foo" refcount(2)

Somit gibt es nun drei separate zval-Container. Noch ein kleines Beispiel mit Arrays

$x = array($c, 'bar');
  echo 'x: '; debug_zval_dump($x);

Hier sieht man den durch debug_zval_dump() verursachten refcount von 2 für $x, eine 2 für das $x[0], weil es eine Kopie ist, sowie eine 1 für das Element $x[1], das nur einen Verweis als Element von $x hat ...

x: array(2) refcount(2){
    [0]=>
    string(3) "foo" refcount(2)
    [1]=>
    string(3) "bar" refcount(1)
  }

... solange man keine Kopien davon erstellt ...

$y = $x[1];
  echo 'x: '; debug_zval_dump($x);

x: array(2) refcount(2){
    [0]=>
    string(3) "foo" refcount(2)
    [1]=>
    string(3) "bar" refcount(2)
  }

... deren Wert nicht verändert wurde.

$x[1] = 'qux';
  echo 'x: '; debug_zval_dump($x);

x: array(2) refcount(2){
    [0]=>
    string(3) "foo" refcount(2)
    [1]=>
    string(3) "qux" refcount(1)
  }

echo "$verabschiedung $name";