Solo le variabili devono essere passate per riferimento


246
// Other variables
$MAX_FILENAME_LENGTH = 260;
$file_name = $_FILES[$upload_name]['name'];
//echo "testing-".$file_name."<br>";
//$file_name = strtolower($file_name);
$file_extension = end(explode('.', $file_name)); //ERROR ON THIS LINE
$uploadErrors = array(
    0=>'There is no error, the file uploaded with success',
    1=>'The uploaded file exceeds the upload max filesize allowed.',
    2=>'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
    3=>'The uploaded file was only partially uploaded',
    4=>'No file was uploaded',
    6=>'Missing a temporary folder'
);

Qualche idea? Dopo 2 giorni ancora bloccato.


2
Una spiegazione migliore per il motivo vijayasankarn.wordpress.com/2017/08/28/…
Anant

Risposte:


515

Assegna il risultato di explodea una variabile e passa quella variabile a end:

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

Il problema è che endrichiede un riferimento, perché modifica la rappresentazione interna dell'array (ovvero fa in modo che il puntatore dell'elemento corrente punti all'ultimo elemento).

Il risultato di explode('.', $file_name)non può essere trasformato in un riferimento. Questa è una restrizione nel linguaggio PHP, che probabilmente esiste per ragioni di semplicità.


12
Grazie mille Risolto il mio problema
Frank Nwoko,

1
@Oswald, possiamo disattivare l'avviso utilizzando error_reporting. È sicuro farlo?
Pacerier,

9
È sicuro spegnere error_reporting. Non è sicuro ignorare ciecamente gli errori. La disattivazione error_reportingè un passo importante verso l'ignoranza cieca degli errori. Nell'ambiente di produzione, disattivare display_errorsinvece e scrivere gli errori in un file di registro.
Oswald,

Non funziona. La risposta qui sotto - doppia parentesi - funziona.
Be '29

Grazie, risparmiami un sacco di tempo!
simon

52

Php 7 uso corretto compatibile:

$fileName      = 'long.file.name.jpg';
$tmp           = explode('.', $fileName);
$fileExtension = end($tmp);

echo $fileExtension;
// jpg

3
Strano. Funziona ma come? Sopprime l'avviso, simile a quello che fa il @prefisso?
Nigel Alderton,

6
Quindi perché l'aggiunta di una parentesi aggiuntiva rimuove l'errore?
Nigel Alderton,

8
Ho studiato questa stranezza e sembra essere un bug? con il parser php dove la doppia parentesi "(())" fa convertire il riferimento in un valore semplice. Altro su questo link .
Callistino,

26
Mi piace questo .. ma non mi piace allo stesso tempo. Grazie per
avermi

4
In php7 verrà comunque emesso un avviso. php.net/manual/en/...
kosta

49

Tutti gli altri ti hanno già indicato il motivo per cui stai ricevendo un errore, ma ecco il modo migliore per fare ciò che vuoi fare: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);


1
Sono d'accordo. Non ha senso utilizzare la manipolazione di stringhe per analizzare i percorsi dei file quando si dispone di API appropriate per farlo.
gd1

18

salva l'array da explode () in una variabile, quindi chiama end () su questa variabile:

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

btw: io uso questo codice per ottenere l'estensione del file:

$ext = substr( strrchr($file_name, '.'), 1);

dove strrchrestrae la stringa dopo l'ultima .e substrtaglia il.


9

Prova questo:

$parts = explode('.', $file_name);
$file_extension = end($parts);

Il motivo è che l'argomento per endviene passato per riferimento, poiché endmodifica l'array facendo avanzare il puntatore interno all'elemento finale. Se non stai passando una variabile, non c'è nulla a cui un riferimento possa puntare.

Vedi endnel manuale di PHP per maggiori informazioni.


8

PHP si lamenta perché si end()aspetta un riferimento a qualcosa che vuole cambiare (che può essere solo una variabile). Tuttavia, si passa explode()direttamente il risultato a end()senza prima salvarlo in una variabile. Nel momento in cui explode()restituisce il tuo valore, esiste solo nella memoria e nessuna variabile punta ad esso. Non è possibile creare un riferimento a qualcosa (o a qualcosa di sconosciuto nella memoria), che non esiste.

O in altre parole: PHP non sa se il valore che gli dai è il valore diretto o solo un puntatore al valore (un puntatore è anche una variabile (numero intero), che memorizza l'offset della memoria, dove il valore effettivo risiede). Quindi PHP si aspetta sempre qui un puntatore (riferimento).

Ma poiché questo è ancora solo un avviso (nemmeno deprecato) in PHP 7, puoi tranquillamente ignorare gli avvisi e utilizzare l'operatore ignore invece di disattivare completamente la segnalazione degli errori per gli avvisi:

$file_extension = @end(explode('.', $file_name));

3
@OskarCalvo Questa è anche la mia filosofia. Ma questo non è un errore: PHP lo considera un "avviso". Ed è stata una "soluzione" alternativa ad altre risposte qui, che nessuno ha menzionato direttamente. Un modo migliore sarebbe quello di salvare il valore explodein una variabile temporanea, come altri hanno scritto qui. Ma ancora: questo non è un errore, quindi è ok per usare questo operatore. PHP è generalmente inadeguato nella gestione degli errori. Pertanto suggerirei di utilizzare set_error_handlere set_exception_handlerper la gestione degli errori e come soluzione più pulita.
mago

4

Proprio come non è possibile indicizzare immediatamente l'array, non è possibile nemmeno chiamare end su di esso. Assegnalo prima a una variabile, quindi chiama end.

$basenameAndExtension = explode('.', $file_name);
$ext = end($basenameAndExtension);

4

end(...[explode('.', $file_name)])ha funzionato dal PHP 5.6. Questo è documentato nella RFC sebbene non nei documenti PHP stessi.


2

Dal momento che alza una bandiera per oltre 10 anni, ma funziona bene e restituisce il valore atteso, un piccolo operatore di stfu è la cattiva pratica più buona che tutti state cercando:

$file_extension = @end(explode('.', $file_name));

0

Manuale ufficiale PHP: end ()

parametri

array

La matrice. Questa matrice viene passata per riferimento perché modificata dalla funzione. Ciò significa che è necessario passargli una variabile reale e non una funzione che restituisce un array perché solo le variabili effettive possono essere passate per riferimento.


3
Fai un preventivo dal manuale ufficiale, non riscriverlo con le tue mani. Inoltre, considera di rendere la tua risposta migliore di quella esistente.
Victor Polevoy,

-1

Innanzitutto, dovrai archiviare il valore in una variabile come questa

$value = explode("/", $string);

Quindi è possibile utilizzare la funzione end per ottenere l'ultimo indice da un array come questo

echo end($value);

Spero che funzionerà per te.


-3

$ file_extension = end (explode ('.', $ file_name)); // ERRORE SU QUESTA LINEA

cambia questa riga come,

$ file_extension = end ( (explode ('.', $ file_name)) ); // nessun errore

La tecnica è semplice si prega di inserire un'altra parentesi per esplodere,

(explode ()) , quindi solo lui può eseguire in modo indipendente ..

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.