Perché i riferimenti sono raramente usati in PHP?

25

Ho alcune conoscenze in C ++ e so che i puntatori sono comunemente usati lì, ma ho iniziato a guardare il codice PHP open source e non vedo mai il codice usando i riferimenti nei metodi.

Invece, il codice usa sempre un valore di ritorno invece di passare il riferimento alla variabile al metodo, che quindi modifica il valore di quella variabile e lo restituisce semplicemente.

Ho letto che usare i riferimenti usa meno memoria, quindi perché non sono usati in PHP?

    
posta Alexander Cogneau 28.02.2013 - 16:56
fonte

7 risposte

47

La tua affermazione che i riferimenti sono usati raramente non è corretta. Come altri hanno già menzionato, ci sono un sacco di funzioni native che usano riferimenti, esempi notevoli includono le funzioni di ordinamento dell'array e preg_match() / preg_match_all() . Se si utilizza una di queste funzioni nel codice, si utilizzano anche riferimenti.

Proseguendo, i riferimenti in PHP sono puntatori non . Dal momento che vieni da uno sfondo C ++ posso capire la confusione, ma i riferimenti PHP sono una bestia completamente diversa, sono alias di un simbolo tavolo . Qualsiasi miglioramento delle prestazioni che potresti aspettarti dai riferimenti C ++ semplicemente non si applica ai riferimenti PHP.

In effetti, nella maggior parte degli scenari il passaggio per valore è più veloce e richiede meno memoria rispetto al passaggio per riferimento. Zend Engine, il nucleo di PHP, utilizza un meccanismo di ottimizzazione copy-on-write che non crea una copia di una variabile fino a quando non viene modificata. Passando per riferimento di solito si interrompe il pattern copy-on-write e si richiede una copia sia che si modifichi il valore o meno.

Non aver paura di usare i riferimenti in PHP quando è necessario, ma non limitarti a fare un tentativo di micro-ottimizzazione. Ricorda che l'ottimizzazione prematura è la radice di tutti i mali .

Ulteriori letture:

risposta data 28.02.2013 - 18:00
fonte
7

PHP fa già una cosa copy-on-write in cui non crea un nuovo valore finché non si modifica qualcosa, quindi non si risparmia molta memoria usando i riferimenti. In questo modo si può anche fare un pasticcio con alcune cose che PHP fa internamente per ridurre l'utilizzo della memoria, rendendo le cose ancora peggiori.

Aggiungete a ciò il fatto che i riferimenti rendono le cose un po 'troppo magiche in generale. L'impostazione predefinita, e quindi ciò che la maggior parte della gente si aspetta, è il pass-by-value; quando passo $i a una funzione, complica tremendamente le cose per cui deve preoccuparsi se quella funzione cambia misteriosamente $i in qualcos'altro interamente, e quindi crea copie difensive per ogni evenienza. (Può già modificare $i se il valore è un oggetto, ma a mio parere non dovrebbe.)

Fondamentalmente, troverei il pass-by-reference utile per i parametri "out", ovvero le variabili che mi aspetto di tornare dalla funzione piuttosto che passare in, la la preg_match ' s &$matches . Anche per le funzioni che chiaramente modificano l'oggetto passato, come sort o array_pop , che sembra un po 'icky ... ma è quello con cui siamo bloccati.

    
risposta data 28.02.2013 - 17:52
fonte
5

PHP è un linguaggio orientato al web.
Le pagine Web vengono servite velocemente e dovrebbero essere leggere.
Il solito programma PHP vive una frazione di secondo e consuma poche centinaia di kilobyte di memoria.
Non serve a tali ottimizzazioni.

    
risposta data 28.02.2013 - 17:01
fonte
3

Alcuni motivi al volo:

  • PHP è un linguaggio di scripting e non ha l'obiettivo di essere usato come un software di base (in pratica, la memoria viene cancellata alla fine dello script),
  • Da PHP5, il riferimento pass-by è implicito per i parametri dell'oggetto (quindi PHP utilizza pass-by-reference "nella tua schiena").
risposta data 28.02.2013 - 17:04
fonte
2

Penso che questa sia solo una scelta degli sviluppatori, niente a che fare con la lingua. Un sacco di codice PHP (incorporato e non) usa riferimenti. Dai un'occhiata alle funzioni degli array in PHP, molti di questi usano riferimenti. preg_match utilizza i riferimenti.

Penso che uno dei motivi per cui gli sviluppatori scelgono di non usare i riferimenti è perché può essere fonte di confusione. Si chiama una funzione e una delle variabili può (o non può) essere aggiornata perché era un riferimento. Quindi, quando esegui il debug, potrebbe non essere chiaro il motivo per cui il valore di $x jsut è cambiato magicamente.

    
risposta data 28.02.2013 - 17:15
fonte
1

Il problema fondamentale con la tua domanda è che tu pensi che questo sia comune anche in C ++. Non lo è. Non ci piacciono i parametri di output e li usiamo il meno possibile - sono solo molto comuni nelle API in stile C.

    
risposta data 28.02.2013 - 18:09
fonte
0

Conosco molte funzioni PHP che lo fanno. Dai un'occhiata a preg_match() per esempio. $matches verrà passato per riferimento

Se vuoi scrivere una funzione per te che prende argomenti per riferimento, usa la seguente sintassi

function byref(&$a, &$b, $c) {
    $a += $c;
    $b += $c;
    return $a * $b;
}

$ a e $ b vengono passati per riferimento $ c viene passato per valore.

    
risposta data 28.02.2013 - 17:08
fonte

Leggi altre domande sui tag