2011-09-17 1 views
19

Ho provato su google, ho provato la documentazione PHP, ho cercato SO per una risposta ma non ho trovato nulla di soddisfacente. Stavo leggendo un libro in cui l'autore ha utilizzato Return by Reference ma non ha mai spiegato di cosa si tratta. il codice utilizzato dall'autore èRitorno per riferimento in PHP

function &getSchool() { 
    return $this->school; 
} 

Qualcuno può spiegare con parole semplici un esempio di questo concetto.

grazie.

+1

I [docs PHP] (http://php.net/manual/en/language.references.return.php) è la risposta definitiva a questo - assicurati di sfogliare tutta la sezione "Riferimenti spiegati". – Jon

+3

Cmon Jon, ho detto che ho già letto la documentazione e ammettere che non l'ho capito abbastanza bene da lì. questa è la ragione per cui ti sto chiedendo qui, sarei grato se tu abbia qualcuno della tua versione da spiegare :) –

+0

Il link fornito da Jon lo spiega bene con l'esempio. – xdazz

risposta

28

Supponiamo di avere questa classe:

class Fruit { 
    private $color = "red"; 

    public function getColor() { 
     return $this->color; 
    } 

    public function &getColorByRef() { 
     return $this->color; 
    } 
} 

La classe ha una proprietà privata e due metodi che consentono di accedervi. Uno restituisce per valore (comportamento predefinito) e l'altro per riferimento. La differenza tra i due è che:

  • Quando si utilizza il primo metodo, è possibile apportare modifiche al valore restituito e tali modifiche non si rifletteranno all'interno della proprietà privata di Fruit perché in realtà si sta modificando una copia del valore della proprietà.
  • Quando si usa il secondo metodo, si sono infatti tornare un alias per Fruit::$color - un nome diverso con il quale si fa riferimento alla stessa variabile . Quindi, se fai qualcosa con esso (compresa la modifica del suo contenuto), stai di fatto eseguendo direttamente la stessa azione sul valore della proprietà.

Ecco il codice per testarlo:

echo "\nTEST RUN 1:\n\n"; 
$fruit = new Fruit; 
$color = $fruit->getColor(); 
echo "Fruit's color is $color\n"; 
$color = "green"; // does nothing, but bear with me 
$color = $fruit->getColor(); 
echo "Fruit's color is $color\n"; 

echo "\nTEST RUN 2:\n\n"; 
$fruit = new Fruit; 
$color = &$fruit->getColorByRef(); // also need to put & here 
echo "Fruit's color is $color\n"; 
$color = "green"; // now this changes the actual property of $fruit 
$color = $fruit->getColor(); 
echo "Fruit's color is $color\n"; 

See it in action.

Attenzione: mi sento in dovere di dire che i riferimenti, mentre essi hanno usi legittimi, sono una di quelle caratteristiche che dovrebbe essere utilizzato solo raramente e solo se avete attentamente considerati alternative primi. I programmatori meno esperti tendono ad abusare dei riferimenti perché vedono che possono aiutarli a risolvere un particolare problema senza allo stesso tempo vedere gli svantaggi dell'uso dei riferimenti (come caratteristica avanzata, le sue sfumature sono tutt'altro che scontate).

+0

Hai spiegato molto bene Jon, grazie :). –

+0

D'altra parte, tutto ciò che è effettivamente nei documenti, ma cosa succede quando il destinatario non menziona la e commerciale, e come si può disabilitare la copia per valore in una classe? Per esempio. per una classe singleton. Perché non ha molto senso sapere che vuoi restituire un valore se devi contare sul chiamante per comportarti bene, vero? – nus

3

L'esempio che hai postato è probabilmente da PHP4 o precedente. Non è più necessario restituire gli oggetti per riferimento poiché vengono quasi sempre eseguiti automaticamente in PHP5 +.

Il ritorno tramite riferimento è utile quando si desidera utilizzare una funzione su trovare a quale variabile deve essere associato un riferimento. Non utilizzare ritorno per riferimento per aumentare le prestazioni. Il motore sarà che lo ottimizzerà automaticamente. Restituisci solo i riferimenti quando hai un valido motivo tecnico per farlo.

Vedi return references in PHP docs

+0

ho già dichiarato che ho già ricevuto la documentazione, e questo non mi spiega nulla. voglio saperne di più. –

+0

Hai letto tutto di http://www.php.net/manual/en/language.references.php? – six8

+3

Ci sono alcuni casi in cui il reso per riferimento potrebbe essere carino, ma io sono un avversario forte. Vedi anche il mio blog: http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html – johannes

14

regola Facile: se fate un & davanti a un nome di funzione in PHP è possibile utilizzare & quando si chiama la funzione (. Cioè il suo valore di ritorno) come se fosse una variabile e non una funzione.

Questo è tutto.


È più facile pensarlo come "PHP che consente di fare riferimento al valore restituito" piuttosto che a PHP che restituisce per riferimento. Come accennato in precedenza, è sufficiente posizionare un & per indicare a PHP che lo si desidera, se non lo si inserisce e provare a fare $var =& somefunction() si otterrà l'errore "Solo le variabili devono essere assegnate per riferimento".

Per chiarire un po 'di confusione con la risposta di Jon. In realtà non è necessario avere due funzioni separate, una che restituisce per riferimento e una che restituisce per valore; al di fuori di alcune convenzioni di progetto. Il & solo consente a di restituire per riferimento, non è forzarlo a restituire per riferimento.

es. stessa funzione utilizzata sia per le assegnazioni di riferimento e non di riferimento

\header('content-type: text/plain'); 

class Demo 
{ 
    protected $example = 'original value'; 

    function & example() 
    { 
     return $this->example; 
    } 
} 

$demo = new Demo; 

#1 - pass by value 

$var1 = $demo->example(); 
$var1 = 'var1 value'; 

echo '$demo->example() => '.$demo->example().PHP_EOL; 
echo PHP_EOL; 

#2 - pass by reference 

$var2 =& $demo->example(); 
$var2 = 'var2 value'; 

echo '$demo->example() => '.$demo->example().PHP_EOL; 
echo '$var1 => '.$var1.PHP_EOL; 
echo '$var2 => '.$var2.PHP_EOL; 
echo PHP_EOL; 

#3 - altering other references 

$var3 =& $demo->example(); 
$var3 = 'var3 value'; 

echo '$demo->example() => '.$demo->example().PHP_EOL; 
echo '$var1 => '.$var1.PHP_EOL; 
echo '$var2 => '.$var2.PHP_EOL; 
echo '$var3 => '.$var3.PHP_EOL; 
echo PHP_EOL; 

exit; 

uscita

$demo->example() => original value 

$demo->example() => var2 value 
$var1 => var1 value 
$var2 => var2 value 

$demo->example() => var3 value 
$var1 => var1 value 
$var2 => var3 value 
$var3 => var3 value 

I riferimenti sono grandi se non hai familiarità con loro si prega di seguire le seguenti regole:

  • considera solo l'utilizzo di riferimenti se si ha a che fare con strutture di dati di grandi dimensioni o strutture non oggettuali simili
  • non fare mai riferimento a un oggetto (se lo si può evitare)
  • consente solo a una funzione di passare per riferimento se il valore viene mantenuto in una proprietà statica o in un attributo sull'oggetto (es. non è una variabile temporanea all'interno della funzione)

Le eccezioni sarebbero ovviamente usi molto utilitari (ad esempio quando si desidera condividere un valore per semplificare il codice per manipolarlo).

Anche in questo caso, MAI riferimento a oggetti (è inutile!)