Il motivo per cui articoli diversi sembrano dire cose diverse è che stanno parlando di diversi tipi di riferimento pass-by.
La cosa principale che determina se un parametro dovrebbe essere superato per riferimento è la firma della funzione stessa e i fondamentali di questo non sono cambiati da Php 4. Considera questo esempio:
function foo( $by_value, &$by_reference ) { /* ... */ }
$a = 1; $b = 2;
foo( $a, $b );
Qui, la variabile esterna $a
viene passato alla funzione per valore, come se fosse assegnato come $by_value = $a;
- cambia in $by_value
non può influenzare $a
. La variabile $b
Tuttavia viene superato come riferimento; Proprio come un incarico della forma $by_reference =& $b;
Ciò significa che esiste una variabile a cui si fa riferimento a due nomi e qualsiasi incarico a uno fungerà da incarico ad entrambi.
Se si passa un valore "ordinario" (una stringa, un numero o un array) per valore, il suo valore è appena copiato nella nuova variabile. A partire da PHP 5: Se si passa un oggetto per valore, tuttavia, succede qualcosa di leggermente diverso: il "valore" copiato è solo un puntatore allo stesso oggetto. Questo significa che se $a
Erano un oggetto, potresti chiamare $by_value->some_property = 42;
e $a->some_property
sarebbe anche 42
. Tuttavia, se hai assegnato un nuovo valore a $by_value
, non influirebbe ancora $a
.
Fino a PHP 5.4, c'era un extra modo per passare un parametro per riferimento, che era "forzare" il comportamento di riferimento a tempo di chiamata. Ciò significava che potresti scrivere foo(&$a, &$b);
e le modifiche di "cattura" apportate a $by_value
dentro il foo()
funzione. Fare affidamento su questo era generalmente una cattiva idea, e quindi è stato rimosso. (È atterrato in 5.4 perché era destinato alla rimozione in PHP 6, ma quel progetto è stato messo in attesa indefinita, con i cambiamenti più piccoli che atterravano in 5.3 e 5.4).
Infine, le funzioni possono Restituzione una variabile per riferimento (come discusso nel manuale qui). Questo è un po 'complicato, in quanto richiede effettivamente di mettere &
in Due Luoghi: all'inizio della Dichiarazione della funzione, per dirlo return
dovrebbe significare "restituire questo riferimento variabile" non "restituire questo valore"; E nel codice che lo chiama, per assegnare una variabile a quel riferimento, piuttosto che semplicemente copiare il suo valore. Ecco un esempio sciocco che combina un parametro di riferimento con un ritorno di riferimento (i due non devono andare insieme, è solo un esempio):
function &bar(&$some_param) { return $some_param; }
$a = 1;
$b =& bar($a);
// $b and $a now point at the same variable, not just the same value
// it was passed into and out of a function, and assigned to a new variable,
// but all those operations were by reference
Si noti che molte persone credono erroneamente che il passaggio di una variabile per riferimento darà loro un vantaggio di performance, e questa era spesso la loro unica ragione per l'utilizzo del pass-by-reference del tempo di chiamata. Questo in realtà è di solito sbagliato, poiché il motore zend che alimenta PHP utilizza una tecnica chiamata "Copia su scrittura" per lasciare più variabili che hanno lo stesso valore che punta allo stesso pezzo di memoria, anche se non sono legati Riferimenti. In effetti, l'assegnazione di riferimento in generale sconfigge Questa ottimizzazione, a causa del modo in cui le traccia del motore sono variabili nello stato di copia-su-scrittura.