Problemas con el PHP $_FILES

Gon
15 de Julio del 2005
Hola,

Trato de configurar Apache con PHP y demás bajo un sistema operativo Windows.

El problema es que parece que cuando envio un archivo desde mi propio PC, nunca llega a guardarse en mi carpeta de archivos temporales.

El código es el siguiente:

<form action="<?=$_SERVER['PHP_SELF']?>" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="<?=get_cfg_var('upload_max_filesize')?>">
<b>Enviar un nuevo archivo (m&aacute;ximo <?=get_cfg_var('upload_max_filesize')?>): </b>
<br />
<input name="userfile" type="file">
<input type="submit" name="upload" value="Enviar">
</form>

if( isset($_POST["upload"]) )
{
echo "name: {$_FILES['userfile']['name']} <br />n";
echo "type: {$_FILES['userfile']['type']} <br />n";
echo "size: {$_FILES['userfile']['size']} <br />n";
echo "tmp_name: {$_FILES['userfile']['tmp_name']} <br />n";
if( !is_uploaded_file($_FILES['userfile']['tmp_name']))
echo "No se ha guardado ningun archivo en ".get_cfg_var('upload_tmp_dir')."<br />n";
}
?>

He comprobado los errores más comunes que he encontrado por ahí:

enctype="multipart/form-data"
upload_max_filesize: 2M
post_max_size: 8M
upload_tmp_dir: C:/Servidor/web/tmp/
max_execution_time: 30
memory_limit: 8M
Upload permitido ('file_uploads')

Alguien puede decirme que es lo que se me escapa?

Gracias.

Loop
15 de Julio del 2005
Disculpa mi ignorancia, en ése script en qué parte subes el archivo ?, yo sólo veo un is_uploaded_file() y eso no es para copiar o mover un archivo eso sólo verifica que haya sido cargado por HTTP POST........

if( !is_uploaded_file($_FILES['userfile']['tmp_name']))
echo "No se ha guardado ningun archivo en ".get_cfg_var('upload_tmp_dir')."<br />n";
} else {
// algo aquí para verificar extenciones y archivos maliciosos
if(copy($_FILES['userfile']['tmp_name'],$directorio_donde_se_guarda.$_FILES['userfile']['tmp_name'])){
echo "El archivo se guardó";
}
}


También se puede usar move_uploaded_file(); en lugar de copy();

Gon
15 de Julio del 2005
Dices muy bien, Loop.

No me he expresado bien. El problema es precisamente que la respuesta que obtengo con el boolean is_uploaded_file($_FILES['userfile']['tmp_name']) es false; Además, $_FILES['userfile']['tmp_name'] está vacio y $_FILES['userfile']['size'] es cero.

Un poquito de ayuda, estoy desesperado.

Loop
15 de Julio del 2005
Mira prueva cambiando $_FILES por $HTTP_POST_FILES que es lo correcto en este caso ..... prueva este script para subir imágenes .....

<?php
/*
* Upload de archivos con php
* By Loop -> [email protected]
*/
if($_FILES['file']){

$subir=false;
/* Extenciones permitidas */
$permitidos=array(".gif",".png",".jpg");

$maxFileSize=60000; // En bytes <- -> Equivalente a 60kb
$ruta_="imgs/"; // Ruta donde será guardada el fichero

$nombre = $_FILES['file']['name'];
$tamanio = $_FILES['file']['size'];

$ord_sb=substr($nombre,-4);

for($i=0;$i<count($permitidos);$i++){
if($ord_sb==$permitidos[$i]){
$subir=true; break;
}
}
if($tamanio>$maxFileSize){
$subir=false;
}
if(!is_uploaded_file($HTTP_POST_FILES['file']['tmp_name'])){
$subir=false;
}

if($subir===true){
if(move_uploaded_file($_FILES['file']['tmp_name'],$ruta_.$nombre)){
echo "Se subió correctamente el fichero";
} else
if(copy($_FILES['file']['tmp_name'],$ruta_.$nombre)){
echo "Se subió correctamente el fichero";
} else {
echo "No se pudo subir el fichero";
}
} else { echo "Tamaño/extención no permitida sólo "; foreach($permitidos as $value){ print $value." "; } echo "<br /> Máximo de tamaño en Bytes ".$maxFileSize; }
}
?>

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" enctype="multipart/form-data">
<input type="file" name="file" /><br />
<input type="submit" value="Enviar" />
</form>

Gon
15 de Julio del 2005
Si vas a limitar las imagenes a gif, jpeg y png, igual te interesa poner esto:
<input name="file" type="file" accept="image/gif,image/x-png,image/jpeg" />

Por otro lado, como variación (no mejor, sino diferente):

$permitidos = array('gif','png','jpeg','jpg');
$tipo = $_FILES['userfile']['type'];

$subir = false;
for($i=0;$i<count($permitidos);$i++){
if(strpos($tipo, $permitidos[$i])){
$subir=true;
break;
}
}
if($subir!==true) {
$_SESSION['errorMsg'] = "No se permiten los archivos de tipo $tipo, solo puede subir imágenes de tipo ".implode(", ",$permitidos);
Header ("Location: {$_SERVER['HTTP_REFERER']}");
die();
}
unset($subir);

Loop
15 de Julio del 2005
Nah, era un ejemplo namás y si te fijas está mejor el que envíe ya que extrae exactamente la extención del archivo es decir .gif .png .jpg .bmp !

Saludos y gracias !

Gon
15 de Julio del 2005
Muchas gracias Loop por tu ayuda, ya he descubierto cual es el problema.

Con $HTTP_POST_FILES no me funcionaría, porque tengo las variables globales desavilitadas (a proposito).

El problema parece ser que si probo el ejemplo en "Local", en mi propio Pc, con las imágenes también en mi ordenador, el script parece no funcionar, pero sólo parece. Esto es así porque el Navegador no almacena las imágenes en su Caché, porque detecta que YA se encuentran en nuestro disco duro y no hay necesidad de "bajarlas".

Cuando pruebo a examinar una imagen de internet (ej: http://www.programacion.com/graficos/logo.jpg), funciona que es de esperar.

De nuevo, muchas gracias por tu ayuda.

Loop
15 de Julio del 2005
En cierta forma tienes razón por eso te decía desde un principio que podías usar move_uploaded_file(); o copy();

independientemente de que si estás en localhost o no, copy(); siempre hace la copia del archivo, move_uploaded_file() efectivamente genera eso que mencionas !

Y otra cosa no hay manera de deshabilitar $HTTP_POST_FILES ni con globals = Off ni a On simplemente esta variable NO ES GLOBAL, pero aún está documentada y puede ser usada en ciertos casos que no sean en ámbito de función sin antes llamar a ..

global $HTTP_POST_FILES

por lo que puede ser usada plenamente !


Saludos y qué bien que ya hayas solucionado el prob =P

Gon
15 de Julio del 2005
No sabria como usar move_uploaded_file(); o copy();, ya que no me llega la ruta del archivo, solo name (tmp_name es una cadena vacia).

Y respecto a $HTTP_POST_FILES, no se porque será, aunque tampoco me supone un problema, pero no la reconoce, ya lo probé antes de usar $_FILES.