Solo las variables deberían pasar por referencia

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'
);

¿Algunas ideas? Después de 2 días todavía atascado.

Frank Nwoko
fuente
2
Una mejor explicación por la razón vijayasankarn.wordpress.com/2017/08/28/…
Anant

Respuestas:

515

Asigne el resultado de explodea una variable y pase esa variable a end:

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

El problema es que endrequiere una referencia, ya que modifica la representación interna de la matriz (es decir, hace que el puntero del elemento actual apunte al último elemento).

El resultado de explode('.', $file_name)no se puede convertir en una referencia. Esta es una restricción en el lenguaje PHP, que probablemente existe por razones de simplicidad.

Oswald
fuente
12
Muchas gracias Resuelto mi problema
Frank Nwoko
1
@ Oswald, podemos desactivar la advertencia usando error_reporting. ¿Es seguro hacerlo?
Pacerier
99
Es seguro apagarlo error_reporting. No es seguro ignorar ciegamente los errores. Apagar error_reportinges un paso importante para ignorar ciegamente los errores. En el entorno de producción, apague en su display_errorslugar y escriba errores en un archivo de registro.
Oswald
No funciona. La respuesta a continuación, paréntesis doble, funciona.
bbe
¡Gracias, ahórreme mucho tiempo!
Simon
52

Uso adecuado compatible con php 7:

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

echo $fileExtension;
// jpg
Sinan Eldem
fuente
3
Extraño. Eso funciona pero ¿cómo? ¿Suprime la advertencia, similar a lo @que hace el prefijo?
Nigel Alderton
66
Entonces, ¿por qué agregar un paréntesis adicional elimina el error?
Nigel Alderton
8
Investigué esta peculiaridad y parece ser un error. con el analizador php donde el paréntesis doble "(())" hace que la referencia se convierta en un valor simple. Más en este enlace .
Callistino 01 de
26
Me gusta esto ... pero no me gusta al mismo tiempo. Gracias por arruinar mi día :-)
billynoah
44
En php7 todavía se emitirá advertencia. php.net/manual/en/…
kosta
49

Todos los demás ya te han dado la razón por la que recibes un error, pero esta es la mejor manera de hacer lo que quieres hacer: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);

ryeguy
fuente
1
Estoy de acuerdo. No tiene sentido utilizar la manipulación de cadenas para analizar las rutas de los archivos cuando tiene las API adecuadas para hacerlo.
gd1
18

guarde la matriz de explotar () en una variable y luego llame a end () en esta variable:

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

por cierto: uso este código para obtener la extensión del archivo:

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

donde strrchrextrae la cadena después de la última .y substrcorta el.

Floern
fuente
9

Prueba esto:

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

La razón es que el argumento para endse pasa por referencia, ya que endmodifica la matriz avanzando su puntero interno al elemento final. Si no está pasando una variable, no hay nada a lo que pueda hacer referencia.

Ver enden el manual de PHP para más información.

Will Vousden
fuente
8

PHP se queja porque end()espera una referencia a algo que quiere cambiar (que solo puede ser una variable). Sin embargo, pasa el resultado de explode()directamente end()sin guardarlo primero en una variable. En el momento en que explode()devuelve su valor, solo existe en la memoria y no tiene puntos variables. No puede crear una referencia a algo (o algo desconocido en la memoria) que no existe.

O en otras palabras: PHP no sabe, si el valor que le da es el valor directo o simplemente un puntero al valor (un puntero también es una variable (entero), que almacena el desplazamiento de la memoria, donde el valor real reside) Entonces PHP espera aquí un puntero (referencia) siempre.

Pero dado que esto sigue siendo solo un aviso (ni siquiera obsoleto) en PHP 7, puede ignorar los avisos y usar el operador ignorar en lugar de desactivar por completo el informe de errores para los avisos:

$file_extension = @end(explode('.', $file_name));
mago
fuente
3
@OskarCalvo Esa es también mi filosofía. Pero esto no es un error: PHP lo trata como un "aviso". Y fue una "solución" alternativa a otras respuestas aquí, que nadie lo mencionó directamente. Una mejor manera sería guardar el valor de explodeen una variable temporal, como otros escribieron aquí. Pero de nuevo: esto no es un error, por lo que está bien usar este operador. PHP es generalmente malo en el manejo de errores. Por lo tanto, sugeriría usar set_error_handlery set_exception_handlerpara el manejo de errores y como solución más limpia.
asistente
4

Del mismo modo que no puede indexar la matriz de inmediato, tampoco puede finalizar la llamada en ella. Asignarlo primero a una variable, luego finalizar la llamada.

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

end(...[explode('.', $file_name)])ha trabajado desde PHP 5.6. Esto está documentado en el RFC, aunque no en los propios documentos PHP.

Tgr
fuente
2

Dado que levanta una bandera durante más de 10 años, pero funciona bien y devuelve el valor esperado, un pequeño operador de stfu es la mala práctica más buena que todos están buscando:

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

Manual oficial de PHP: end ()

Parámetros

array

La matriz Este conjunto se pasa por referencia porque la función lo modifica. Esto significa que debe pasarle una variable real y no una función que devuelva una matriz porque solo las variables reales pueden pasarse por referencia.

evenvi
fuente
3
Haga una cita del manual oficial, no lo reescriba con sus propias manos. Además, considere hacer su respuesta mejor que la existente.
Victor Polevoy
-1

Primero, deberá almacenar el valor en una variable como esta

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

Luego puede usar la función final para obtener el último índice de una matriz como esta

echo end($value);

Espero que funcione para ti.

Jailendra Rajawat
fuente
-3

$ file_extension = end (explotar ('.', $ nombre_archivo)); // ERROR EN ESTA LÍNEA

cambia esta línea como,

$ file_extension = end ( (explotar ('.', $ nombre_archivo)) ); //sin errores

La técnica es simple, coloca un paréntesis más para explotar,

(explotar ()) , entonces solo puede funcionar de forma independiente.

Manu RS
fuente