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.


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.


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

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


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.


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.


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

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

4

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


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

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.


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.


-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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.