Anche tu hai ricevuto questo strano errore "Only variables can be passed by reference" in php? Non hai idea del come si sia verificato e di come risolverlo, beh! Vediamo se riusciamo a fare un pò di chiarezza e soprattutto vediamo di risovlerlo definitivamente.
Prima di vedere come risolvere l'errore "Only variables can be passed by reference", facciamo una piccola premessa sui passaggi dei parametri per valore e per riferimento ad una funzione. Nei linguaggi di programmazione i parametri passati da una funzione possono essere passati in due modi, per valore o per riferimento, a seconda del tipo passato e dalla definizione (signature) della funzione.
Passaggi dei parametri per valore
Quando passi un parametro per valore ad una funzione, effettivamente stai passando una copia della variabile e del suo corrispettivo valore, quindi qualunque modifica a questa variabile all'interno della funzione (black box) non modifica la variabile passata alla chimata a funzione ma solo la sua copia.
Passaggi dei parametri per riferimento
Quando passi un parametro per riferimento ad una funzione, questa volta stai passando un puntatore alla cella di memoria del valore della variabile, pertanto qualunque modifica a questa variabile all'interno della funzione (black box) ne modifica effettivamente il valore. Una funzione definisce il passaggio di parametri per riferimento, anteponendo il carattere ampersand "&" (e commerciale) al parametro che accetta il valore per riferimento.
Detto questo, il linguaggio PHP non fà eccezione a queste due metodologie di passaggi dei parametri alle chiamate di funzione.
Come certamente saprai il php è dotato di vaste librerie con funzioni già definite che agevolano notevolmente il lavoro dello sviluppatore, spesso però le usiamo (le funzioni di libreria) senza studiarne la signature (la definizione), per poi ritrovarsi l'errore "Only variables can be passed by reference" senza capirne l'origine.
Perchè si manifesta l'errore Only variables can be passed by reference
Questo errore si è manifestato perchè probabilmente avete fatto una chiamata ad una funzione che accetta come parametro un valore per riferimento, ed invece avete passato direttamente un "valore" o una variabile non instanziata. Ad es. avete scritto in questo modo:
array_push(array(1,2,3),4);
Con questo codice la funzione array_push cerca di modificare l'allocazione di memoria del primo parametro (l'array), ma questo non essendo stato instanziato (tramite assegnamento o operatore new) non può avere un riferimento in memoria e pertanto l'interprete php si blocca mostrando l'errore "Only variables can be passed by reference".
Infatti se andiamo a vedere la definizione della funzione (la signature) di array_shift questa si presenta così:
int array_push ( array &$array , mixed $value1 [, mixed $... ] ) //presa da php.net
Notate come il primo parametro debba essere un array, e questo viene passato per riferimento con il carattere "&" di ampersand.
Come abbiamo detto i passaggi di parametri per riferimento, puntano direttamente alla cella di memoria interessata, se non gestiti correttamente possono creare degli errori in memoria, mandando in crash l'applicazione se non l'intero sistema. Per tale motivo nelle ultime versioni del PHP, gli sviluppatori del linguaggio hanno imposto maggiori restrizioni all'uso "allegro" dei parametri nelle chiamate a funzione, ed il messaggio di errore lo dice chiaramente "solamente le variabili possono essere passate per riferimento".
Come risolvere l'errore Only variables can be passed by reference
Visto che solo le variabili possono essere passate per riferimento in php, per risolvere questo errore non ci resta che assegnare il nostro array ad una variabile prima di passarlo come parametro alla funzione array_push, in questo modo:
$my_array = array(1,2,3);
array_push($my_array,4);
Con questo codice non si verificherà più l'errore "Only variables can be passed by reference".
Conclusioni
Questo tipo di errore e simili hanno creato diversa confusione nella community php, ma come già accennato dalla versione 5 in poi il linguaggio php comincia ad essere più restrittivo nell'uso della sintassi, dei tipi e delle chiamate a funzione, con un andamento verso un linguaggio di programmazione sempre più strongly typed ed object oriented di quanto non lo sia attualmente
Chiunque voglia aggiungere qualcosa o porre una domanda sull'errore "Only variables can be passed by reference", può farlo liberamente tramite lo spazio dei commenti, ogni vostro intervento sarà gradito e contribuirà ad accrescere la discussione.