imposibilidad de subir ficheros con php [Solucionado]
Hola , estoy intentando subir un fichero con php a una base de datos mysql con cherokke cmo servidor. El codigo de la pagina inicial es el siguiente
<HTML>
<HEAD>
<TITLE>Binario a BD</TITLE>
</HEAD>
<BODY>
<?php
if (isset($_GET['proceso'])){
echo $_GET['proceso']."<br>";
}
?>
<FORM enctype="multipart/form-data" method="post" action="insertar.php">
Archivo: <INPUT type="file" name="archivo" size="30">
<INPUT type="submit" name="submit" value="Subir archivo">
</FORM>
</BODY>
</HTML>La pagina que enlaza es
<?php
//Primero, arranca el bloque PHP y checkea si el archivo tiene nombre. Si no fue asi, te remite de nuevo al formulario de inserción:
// No se comprueba aqui si se ha subido correctamente.
if (empty($_FILES['archivo']['name'])){
header("location: formulario.php?proceso=falta_indicar_fichero"); //o como se llame el formulario ..
exit;
}
?> nombre<?echo $_FILES['archivo']['name'];
?> peso<?echo $_FILES['archivo']['size'];
?> tipo<?echo $_FILES['archivo']['type'];
//establece una conexión con la base de datos.
$conexion = mysql_connect("localhost","usuarioweb","usuarioweb") or die("No se pudo realizar la conexion con el servidor.");
mysql_select_db("audio",$conexion) or die("No se puede seleccionar BD"); // tu_bd es el nombre de la Base de datos .. por siaca.
// archivo temporal (ruta y nombre).
$binario_nombre_temporal=$_FILES['archivo']['tmp_name'] ;
// leer del archvio temporal .. el binario subido.
// "rb" para Windows .. Linux parece q con "r" sobra ...
$binario_contenido = addslashes(fread(fopen($binario_nombre_temporal, "r"), filesize($binario_nombre_temporal)));
// Obtener del array FILES (superglobal) los datos del binario .. nombre, tabamo y tipo.
$binario_nombre=$_FILES['archivo']['name'];
$binario_peso=$_FILES['archivo']['size'];
$binario_tipo=$_FILES['archivo']['type'];
//insertamos los datos en la BD.
$consulta_insertar = "INSERT INTO videos (id, binario, nombre, peso, tipo) VALUES ('', '$binario_contenido', '$binario_nombre', '$binario_peso', '$binario_tipo')";
mysql_query($consulta_insertar,$conexion) or die("No se pudo insertar los datos en la base de datos.");
header("location: listar_imagenes.php"); // si ha ido todo bien
exit;
?>
Cuando intento insertar obtengo lo siguiente
nombresong46.ogg peso0 tipo
Warning: fread(): supplied argument is not a valid stream resource in /home/carlos/cherokee/video/insertar.php on line 22
No se pudo insertar los datos en la base de datos.El archivo esta llegando pero su tamaño parece ser de 0 como si estuviera vacio cuando esu tamaño es de 3.6 MB
En el fichero php.ini de /etc/php5/cgi tengo lo siguiente ( es decir tengo habilitado subir archivos de como maximo hasta 6M y enviar por post hasta 8M)
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
; Whether to allow HTTP file uploads.
file_uploads = On
; Temporary directory for HTTP uploaded files (will use system default if not
; specified).
upload_tmp_dir = /tmp
; Maximum allowed size for uploaded files.
upload_max_filesize = 6M
; Maximum size of POST data that PHP will accept.
post_max_size = 8M
- Inicie sesión o regístrese para enviar comentarios
- 1396 lecturas


Mira atentamente qué está mal en el código:
$binario_contenido = addslashes(fread(fopen($binario_nombre_temporal, "r"), filesize($binario_nombre_temporal)));
Primero, verifica si el archivo se ha subido correctamente:
if($_FILES["file"]["error"] == UPLOAD_ERR_OK){
foobar; // Hacer aquí lo necesario para guardar datos.
}
Lo siguiente es correcto:
$handle = @fopen($binario_nombre_temporal, "rb"); // Usa SIEMPRE la bandera 'b', por Portabilidad
if ($handle) {
while (!feof($handle)) {
$binario_contenido.= fgets($handle, 4096);
}
fclose($handle);
}
Y:
$consulta_insertar = "INSERT INTO videos (id, binario, nombre, peso, tipo) VALUES ('', '$binario_contenido', '$binario_nombre', '$binario_peso', '$binario_tipo')";
Recuerda, $_FILES['file']['type']; se apoya en el User-agent y no es un método fiable para obtener el MIME de un archivo determinado. Otras funciones sí lo haces, como al manegar Imgaénes; con image_type_to_mime_type() y exif_imagetype()
O, puedes simplemente usar file_get_contents() a menos que el archivo sea muy grande.
$binario_contenido = addslashes($file_get_contents($binario_nombre_temporal));
Por favor lee el Manual para más información:
http://www.php.net/manual/es/features.file-upload.post-method.php
He modificado para obtener los datos del fichero, como lo que quiero subir no es una imagen sino un *.ogg imagesize no me vale, asi que he optado por filesize
<?php//Primero, arranca el bloque PHP y checkea si el archivo tiene nombre. Si no fue asi, te remite de nuevo al formulario de inserción:
// No se comprueba aqui si se ha subido correctamente.
if($_FILES["file"]["error"] != UPLOAD_ERR_OK){
header("location: formulario.php?proceso=falta_indicar_fichero"); //o como se llame el formulario ..
exit;
} //establece una conexión con la base de datos.
$conexion = mysql_connect("localhost","usuarioweb","usuarioweb") or die("No se pudo realizar la conexion con el servidor.");
mysql_select_db("audio",$conexion) or die("No se puede seleccionar BD"); // tu_bd es el nombre de la Base de datos .. por siaca.
// archivo temporal (ruta y nombre).//
$binario_nombre_temporal=$_FILES['archivo']['tmp_name'] ; // leer del archvio temporal .. el binario subido.// "rb" para Windows .. Linux parece q con "r" sobra ...
//$binario_contenido = addslashes(fread(fopen($binario_nombre_temporal, "r"), filesize($binario_nombre_temporal))); $handle = @fopen($binario_nombre_temporal, "rb"); // Usa SIEMPRE la bandera 'b', por Portabilidad
if ($handle) {
while (!feof($handle)) {
$binario_contenido.= fgets($handle, 4096);
}
fclose($handle);
} // Obtener del array FILES (superglobal) los datos del binario .. nombre, tabamo y tipo.
$binario_nombre=$_FILES['archivo']['name'];
$binario_tipo=image_type_to_mime_type($binario_nombre);
$binario_peso=filesize($binario_nombre);
echo
'peso '. $binario_peso;echo 'tipo '. $binario_tipo;
//insertamos los datos en la BD.
$consulta_insertar = "INSERT INTO videos (id, binario, nombre, peso, tipo) VALUES ('', '$binario_contenido', '$binario_nombre', '', '$binario_tipo')";
//mysql_query($consulta_insertar,$conexion) or die("No se pudo insertar los datos en la base de datos.");
//header("location: listar_imagenes.php"); // si ha ido todo bien
exit;
?>
La informacion de filesize, la he cogido de aqui
Sin embargo sigue sin cogerme el tamaño del fichero, dandome el siguiente error, el tipo de fichero me ddice que es
application/octet-stream y el fichero aparece como song46.ogg que es el fichero que quiero subir
Warning: filesize() [function.filesize]: stat failed for song46.ogg in /home/carlos/cherokee/video/insertar.php on line 33peso tipo application/octet-stream
EDITO:
He probado a escribir $binario_contenido y si tiene contenido
Ya obtengo el tipo y el tamaño pero no puedo insertar
<?php//Primero, arranca el bloque PHP y checkea si el archivo tiene nombre. Si no fue asi, te remite de nuevo al formulario de inserción:
// No se comprueba aqui si se ha subido correctamente.
if($_FILES["file"]["error"] != UPLOAD_ERR_OK){
header("location: formulario.php?proceso=falta_indicar_fichero"); //o como se llame el formulario ..
exit;
} //establece una conexión con la base de datos.
$conexion = mysql_connect("localhost","usuarioweb","usuarioweb") or die("No se pudo realizar la conexion con el servidor.");
mysql_select_db("audio",$conexion) or die("No se puede seleccionar BD"); // tu_bd es el nombre de la Base de datos .. por siaca.
// archivo temporal (ruta y nombre).//
$binario_nombre_temporal=$_FILES['archivo']['tmp_name'] ; // leer del archvio temporal .. el binario subido.// "rb" para Windows .. Linux parece q con "r" sobra ...
//$binario_contenido = addslashes(fread(fopen($binario_nombre_temporal, "r"), filesize($binario_nombre_temporal))); $handle = @fopen($binario_nombre_temporal, "rb"); // Usa SIEMPRE la bandera 'b', por Portabilidad
if ($handle) {
while (!feof($handle)) {
$binario_contenido.= fgets($handle, 4096);
}
fclose($handle);
} // Obtener del array FILES (superglobal) los datos del binario .. nombre, tabamo y tipo.
$binario_nombre=$_FILES['archivo']['name'];
$binario_tipo=image_type_to_mime_type($binario_nombre);
$binario_peso=$_FILES['archivo']['size'];
echo
'peso '. $binario_peso .'<br>';echo 'tipo '. $binario_tipo.'<br>';
//insertamos los datos en la BD.
$consulta_insertar = "INSERT INTO videos (id, binario, nombre, peso, tipo) VALUES ('', '$binario_contenido', '$binario_nombre', '$binario_peso', '$binario_tipo')";
//echo 'query ' . $consulta_insertar.'\n';
mysql_query($consulta_insertar,$conexion) or die("No se pudo insertar los datos en la base de datos.");
//header("location: listar_imagenes.php"); // si ha ido todo bien
exit;
?>
Se obtiene lo siguiente
peso 3766867tipo application/octet-stream
No se pudo insertar los datos en la base de datos.
La tabla de la BBDD es en el database audio y se llama videos
id int(10) unsigned NO PRI NULL auto_incrementbinario blob NO NULL
nombre varchar(255) NO ''
peso varchar(15) NO ''
tipo varchar(25) NO ''
Prueba a meter el fichero codificado en base64:
<?php//$handle = @fopen($binario_nombre_temporal, "rb"); // Usa SIEMPRE la bandera 'b', por Portabilidad
//if ($handle) {
// while (!feof($handle)) {
// $binario_contenido.= fgets($handle, 4096);
// }
// fclose($handle);
//} $binario_contenido = file_get_contents($binario_nombre_temporal);
$b64_contenido = base64_encode($binario_contenido); // Obtener del array FILES (superglobal) los datos del binario .. nombre, tabamo y tipo.
$binario_nombre=$_FILES['archivo']['name'];
$binario_tipo=image_type_to_mime_type($binario_nombre);
$binario_peso=$_FILES['archivo']['size'];
echo
'peso '. $binario_peso .'<br>';echo 'tipo '. $binario_tipo.'<br>'; //insertamos los datos en la BD. $consulta_insertar = "INSERT INTO videos (id, binario, nombre, peso, tipo) VALUES ('', '$b64_contenido', '$binario_nombre', '$binario_peso', '$binario_tipo')";
//echo 'query ' . $consulta_insertar.'\n';
mysql_query($consulta_insertar,$conexion) or die("No se pudo insertar los datos en la base de datos.");
//header("location: listar_imagenes.php"); // si ha ido todo bien
exit;
?>
Igualmente he utilizado la función file_get_contents() que es más sencilla.
Espero que te sea de ayuda.
ya esta la query
$consulta_insertar = "INSERT INTO videos (id, binario, nombre, peso, tipo) VALUES ('', '".$b64_contenido."', '".$binario_nombre."', '".$binario_peso."', '".$binario_tipo."')";Y ademas si le das permisos de insercion al usuario pues es posible insertar
Aún así, en un entorno de producción, NO recomiendo meter archivos dentro de una DB, particularmente si son grandes y especialmente si están codificados en base64, ya que podría significar una carga enorme para el servidor y la DB.
Lo que haría, sería guardar el Archivo en el disco, y en el campo de Archivo de la DB, guardar la Ruta completa al archivo subido. Luego, al hacer un Query para recuperar los datos, se obtiene el campo Archivo, y con alguna función descargas el archivo en el disco.
Todo esto, sólo es una recomendación es para un Entorno de Producción.
Si, en un entorno de produccion es lo que se hace, lo hago habitualmente con java, pero esto es una forma de autoaprendizaje de php. Tambien depende del volumen todal de ficheros y de la parametrizacion del servidor y de la BBDD de lo cual se podria hablar largo y tendido.