Domanda

Ricevo segnali contrastanti dappertutto.

Uso l'ampa e per passare le variabili per riferimento o no?

Il seguente link sembra dirmi che è deprecato e non è più necessario:
http://gtk.php.net/manual/en/html/tutorials/tutorials.changes.references.html

Ma thread come questi mi fanno meravigliare:
Call-Time pass per riferimento deprecato?
PHP e AMPERSAND

Lasciami definire la mia domanda come esempio.

Se faccio una funzione, usando PHP 5.5.5:

function recurring_mailer_form($form, $form_state) 
{

}

È lo stesso di:

function recurring_mailer_form($form, &$form_state) 
{

}

?

È stato utile?

Soluzione

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.

Altri suggerimenti

No non lo è.

  • Gli oggetti vengono sempre automaticamente passati come riferimenti (Informazioni! Vedi sotto per ulteriori informazioni importanti!)

  • Dichiarare i parametri come riferimenti devono avvenire nella definizione della funzione:

    function test(&$var) {}
    

    Non Al momento di chiamarlo:

    // wrong
    $var = '123';
    test(&$var);
    


Se si passa un oggetto come al solito, è possibile modificare lo stato (proprietà) dell'oggetto.
Assumilo $obj è un'istanza della classe TestClass che contiene una variabile membro chiamata hello (Fai clic qui per un esempio completo su ideone.com):

function modify($obj) { $obj->hello = 'world (modified)!'; }

$obj->hello = 'world';
modify($obj);
var_dump($obj->hello);  // outputs "world (modified!)"

Questo dovrebbe essere autoesplicativo. Ora, usando lo stesso codice ma assegnando un altro valore a $obj Invece modificando lo stato dell'oggetto non comporta modifiche (→ Ideone.com):

function modify($obj) { $obj = 42; }
// ...
var_dump($obj->hello);  // outputs "world"

Accettare solo il parametro esplicitamente come riferimento ci fornisce la capacità di modificare completamente il contenuto della variabile (→ Ideone.com):

function modify(&$obj) { $obj = 42; }
// ...
var_dump($obj);         // outputs "42"

No, quelli non sono gli stessi. PHP 5.4+ rileva solo su chiamata se è necessario un riferimento quando la funzione viene chiamata controllando la dichiarazione.

Quindi no, non deprecato poiché è necessario l'operatore di riferimento nella Dichiarazione della funzione se questo è il tuo utilizzo previsto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top