Foros del Web » Programando para Internet » PHP »

Leer directorio de archivos y cargarlos a BD como Bytea

Estas en el tema de Leer directorio de archivos y cargarlos a BD como Bytea en el foro de PHP en Foros del Web. Buenas tardes estimados, solicito su ayuda para corregir este script que ya tiene días dándome problemas y no encuentro la manera de solucionarlo. No se ...
  #1 (permalink)  
Antiguo 02/05/2017, 14:18
Avatar de Heiroon  
Fecha de Ingreso: junio-2010
Ubicación: Caracas, Venezuela - Por ahora...
Mensajes: 495
Antigüedad: 13 años, 10 meses
Puntos: 63
Exclamación Leer directorio de archivos y cargarlos a BD como Bytea

Buenas tardes estimados,

solicito su ayuda para corregir este script que ya tiene días dándome problemas y no encuentro la manera de solucionarlo. No se si este del todo correcto, por lo cual pido su auxilio. Como dice el titulo, la idea es verificar dentro de un directorio temporal una carpeta, leer los archivos que contiene y uno por uno, guardarlos en la BD como un bytea.

El problema es que una vez que intento descargar el archivo, el mismo viene corrupto y con variaciones de tamaño bastantes considerables. A continuación les dejo los scripts de subida y bajada.

De antemano muchas gracias por su apoyo.

Subida

Código PHP:
                $path  "../../../../tmp/" $attach_folder_key "/";
                
$files array_diff(scandir($path), array('.''..'));
                
                
//Si se adjuntaron archivos 
                
if(is_dir($path) && (count($files) > 0)){
                    
                    if( !isset(
$id_pun_int) ){
                        
$queryId "SELECT id_pun_int FROM general.puntos_interes ORDER BY id_pun_int DESC LIMIT 1";
                        
$db->Query($queryId);
                        
$id_pun_int $db->Fresult();
                    }
                    
                    foreach(
$files as $fileName){
                        
                        
$filePath $path $fileName;
                        
$safeFileName pg_escape_string($fileName); //name
                        
                        
$p fopen($filePath,'rb');
                        
$fsize filesize($filePath); // size
                        
$data fread($p$fsize);
                        
                        
$dat  pg_escape_bytea($data); // bytea
                                                
                        
$mime getFileMimeType($filePath); // mime
                        
                        
$queryInsert "    INSERT INTO general.recursos 
        
                                                (nom_rec, mim_rec, tam_rec, raw_dat_rec) 
                            
                                            VALUES 
                            
                                                ('$safeFileName', '$mime', '$fsize', '$dat'::bytea)
        
                                            RETURNING id_rec"
;
                        
                        
$db->Query($queryInsert);
                        
$id_rec$db->Fresult();
                        
                        
$queryAsoc "INSERT INTO general.puntos_interes_recursos (id_pun_int, id_rec) VALUES ($id_pun_int, $id_rec)";
                        
$db->Query($queryAsoc);
                    }
                } 

Descarga

Código PHP:
if( !isset($_REQUEST)){
        die(
_('403 - Forbidden.'));
    }
    
    if( !isset(
$_REQUEST["id_rec"])){
        die(
_('Faltan parámetros.'));
    }
    
    
$ConnPG = new pgdb();
    if (!
$ConnPG->Connect(false))
    {
        die(
_('No se pudo realizar la conexión.'));
    }
    
    
$query"SELECT * FROM general.recursos WHERE id_rec = " $_REQUEST["id_rec"];
    
    
$ConnPG->Query($query);
    
$fileData $ConnPG->Fobject();
    
    
$file pg_unescape_bytea($fileData->raw_dat_rec);
    
$name $fileData->nom_rec;
    
$mime $fileData->mim_rec;
    
$size $fileData->tam_rec;
    
    
header('Connection: Keep-Alive');
    
header('Expires: 0');
    
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    
header('Pragma: public');
    
header('Content-Length: ' $size);
    
header('Content-Type: ' $mime);
    
header('Content-Disposition: attachment; filename=' $name);
    
    echo 
$file
Cualquier pregunta o información requerida estoy a la orden.
__________________
Gmail : [email protected]
Twitter: @heiroon

I'm back!

Última edición por Heiroon; 02/05/2017 a las 14:24
  #2 (permalink)  
Antiguo 02/05/2017, 14:49
alvaro_trewhela
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Leer directorio de archivos y cargarlos a BD como Bytea

Prueba con file_get_contents en cambio de fread a ver como corre
  #3 (permalink)  
Antiguo 02/05/2017, 14:58
Avatar de Heiroon  
Fecha de Ingreso: junio-2010
Ubicación: Caracas, Venezuela - Por ahora...
Mensajes: 495
Antigüedad: 13 años, 10 meses
Puntos: 63
Respuesta: Leer directorio de archivos y cargarlos a BD como Bytea

Muchas gracias por responder alvaro_trewhela,

bueno, te comento, hice el cambio como me sugeriste, si bien los archivos se cargan aparentemente de forma correcta, siguen descargandose corruptos. Como mencione anteriormente, no se si el problema este en la carga como tal o en la propia descarga del archivo.


Este es el segmento de código que modifique

Código PHP:

$filePath 
$path $fileName;
                        
$safeFileName pg_escape_string($fileName); //name
                        
                        /*$p = fopen($filePath,'rb');
                        $data = fread($p, $fsize);*/
                        
                        
$data  file_get_contents($filePath);
                        
$dat  pg_escape_bytea($data); // bytea
                        
                        
$fsize filesize($filePath); // size
                        
$mime getFileMimeType($filePath); // mime
                        
                        
$queryInsert "    INSERT INTO general.recursos 
        
                                                (nom_rec, mim_rec, tam_rec, raw_dat_rec) 
                            
                                            VALUES 
                            
                                                ('$safeFileName', '$mime', '$fsize', '$dat'::bytea)
        
                                            RETURNING id_rec"
;
                        
                        
$db->Query($queryInsert);
                        
$id_rec$db->Fresult(); 
__________________
Gmail : [email protected]
Twitter: @heiroon

I'm back!
  #4 (permalink)  
Antiguo 02/05/2017, 15:16
alvaro_trewhela
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Leer directorio de archivos y cargarlos a BD como Bytea

mmm entonces en la descarga manda directamente la data del archivo no escapes nada, ve que tal...
  #5 (permalink)  
Antiguo 02/05/2017, 15:34
Avatar de Heiroon  
Fecha de Ingreso: junio-2010
Ubicación: Caracas, Venezuela - Por ahora...
Mensajes: 495
Antigüedad: 13 años, 10 meses
Puntos: 63
Respuesta: Leer directorio de archivos y cargarlos a BD como Bytea

Hice tal cual me indicaste y lo mismo. Adicionalmente, probe de dos formas

Directamente

Código PHP:
    //$file = $fileData->raw_dat_rec;
    
$name $fileData->nom_rec;
    
$mime $fileData->mim_rec;
    
$size $fileData->tam_rec;
    
    
header('Connection: Keep-Alive');
    
header('Expires: 0');
    
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    
header('Pragma: public');
    
header('Content-Length: ' $size);
    
header('Content-Type: ' $mime);
    
header('Content-Disposition: attachment; filename=' $name);
    
    echo 
$fileData->raw_dat_rec
Y aplicando un Flush

Código PHP:

//$file = $fileData->raw_dat_rec;
    
$name $fileData->nom_rec;
    
$mime $fileData->mim_rec;
    
$size $fileData->tam_rec;
    
    
header('Connection: Keep-Alive');
    
header('Expires: 0');
    
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    
header('Pragma: public');
    
header('Content-Length: ' $size);
    
header('Content-Type: ' $mime);
    
header('Content-Disposition: attachment; filename=' $name);
    
    
ob_clean();
    
flush();
    
readfile($fileData->raw_dat_rec);
    exit; 
El archivo originalmente tiene 23,5 KB. Con el primer método me devuelve un archivo de 2,54 KB y en el segundo me devuelve uno de 47,0 KB. Es decir el doble de peso. Algo muy raro esta pasando y no tengo idea. Cuando guardo el archivo, tambien guardo el peso en bytes y el que se guarda es de 24101, que es congruente con el peso aproximado de la imagen.

Ya de verdad no se que mas hacer... A mi parecer el código esta bien. Pero no logro ver donde esta la falla.
__________________
Gmail : [email protected]
Twitter: @heiroon

I'm back!
  #6 (permalink)  
Antiguo 03/05/2017, 20:29
alvaro_trewhela
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Leer directorio de archivos y cargarlos a BD como Bytea

Mira esto hice con mysqli y me anduvo muy bien:

Carga:

Código PHP:
Ver original
  1. <?php
  2.  
  3. //Config
  4.  
  5. $d = "dir/subdir"; //Direction without / final
  6.  
  7. $db_data = array(
  8. "server" => "server", //DB server
  9. "user" => "user", //DB user
  10. "pass" => "pass", //DB pass
  11. "db" => "db", //Data Base
  12. "table" => "table" //DB table
  13. );
  14.  
  15. //End config
  16.  
  17. $mysqli = new mysqli($db_data["server"], $db_data["user"], $db_data["pass"], $db_data["db"]);
  18.  
  19. $dir = scandir($d);
  20.  
  21. for($k=0;$k<sizeof($dir);$k++){
  22.     if($dir[$k] != "." && $dir[$k] != ".." && !is_dir("$d/".$dir[$k])){
  23.     $file = "$d/".$dir[$k];
  24.     $name = $dir[$k];
  25.     $size = filesize($file);
  26.    
  27.     $fo = finfo_open(FILEINFO_MIME_TYPE);
  28.     $mime = finfo_file($fo, $file);
  29.     finfo_close($fo);
  30.    
  31.     $fop = fopen($file,"r");
  32.     $data = $mysqli->real_escape_string(fread($fop,$size));
  33.     fclose($fop);
  34.  
  35.     $mysqli->query("INSERT INTO ".$db_data["table"]." (name, size, mime, data) VALUES ('$name', '$size', '$mime', '$data')");
  36.     }
  37. }
  38.  
  39. ?>

Download:

Código PHP:
Ver original
  1. <?php
  2.  
  3. $idFile = 3; //someway to get the id of file
  4.  
  5.  
  6. //Config
  7.  
  8. $db_data = array(
  9. "server" => "server", //DB server
  10. "user" => "user", //DB user
  11. "pass" => "pass", //DB pass
  12. "db" => "db", //Data Base
  13. "table" => "table" //DB table
  14. );
  15.  
  16. //End config
  17.  
  18. $mysqli = new mysqli($db_data["server"], $db_data["user"], $db_data["pass"], $db_data["db"]);
  19.  
  20. $file = $mysqli->query("SELECT * FROM ".$db_data["table"]." WHERE id='$idFile'")->fetch_assoc();
  21. $name = $file["name"];
  22. $size = $file["size"];
  23. $data = $file["data"];
  24.  
  25. header('Content-Description: File Transfer');
  26. header('Content-Type: application/octet-stream');
  27. header('Content-Disposition: attachment; filename="'.$name.'"');
  28. header('Expires: 0');
  29. header('Cache-Control: must-revalidate');
  30. header('Pragma: public');
  31. header('Content-Length: '.$size);
  32. echo $data;
  33.  
  34. ?>

Y mi tabla:

id: primary ai
name: varchar
size: int
mime: varchar
data: longblob

Tu dale la longitud y cotejamiento a toda la tabla

Eso, falta las validaciones, pero espero haber ayudado.

Saludos

Última edición por alvaro_trewhela; 04/05/2017 a las 09:00
  #7 (permalink)  
Antiguo 04/05/2017, 13:24
Avatar de Heiroon  
Fecha de Ingreso: junio-2010
Ubicación: Caracas, Venezuela - Por ahora...
Mensajes: 495
Antigüedad: 13 años, 10 meses
Puntos: 63
Respuesta: Leer directorio de archivos y cargarlos a BD como Bytea

Hola, muy buenas!

nuevamente muchas gracias por el seguimiento que le has hecho a mi caso alvaro_trewhela, aun sigo estancado con el problema, pero sin embargo pude determinar que mi código esta bien y funciona correctamente. Al parecer el problema tiene que ver directamente con el entorno en el que se esta ejecutando. Acá dispongo de varios servidores, pero el problema es que los entornos son distintos. En el que estaba desarrollando, tiene Apache/2.2.17 (Fedora) y PHP/5.3.8. Probé en otro entorno donde tengo Apache/2.2.15 (CentOS) y PHP/5.5.27, allí la descarga se ejecutó perfectamente me retornó todos los archivos sin problema y todo bien.

Pienso que el problema debe estar por esta dirección, pero como se puede ver, no estoy utilizando ninguna funcionalidad que sea incompatible entre las versiones de Apache y PHP que mencioné. En este orden de ideas, si alguien tiene alguna idea de que pueda estar ocurriendo, si hay que establecer alguna configuración especifica en el servidor o algo de esto, por favor le agradecería su apoyo.

De igual forma, cualquier duda o información adicional que necesiten, estoy a su total disposición.

Actualización:

Servidor con PHP 5.3.8

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8
Connection:keep-alive
Cookie:GTRMAX=5iub8t5ba6fpt91651os441vs5
Host:hpartidas.webserver2a-local.sigis.com.ve
Referer:http://hpartidas.webserver2a-local.s..._pun_int=59025
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36

Response Headers

Cache-Control:must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive, Keep-Alive
Content-Disposition:attachment; filename=Apocalypse_starring_Bruce_Willis.jpg
Content-Language:es
Content-Length:24101
Content-Type:image/jpeg
Date:Wed, 03 May 2017 21:48:02 GMT
Expires:0
Keep-Alive:timeout=120
Pragma:public
Server:Apache/2.2.17 (Fedora)
Set-Cookie:GTRMAX=g4dhbh3tdkhql7m9iiovlvbqn3; expires=Wed, 03-May-2017 23:48:02 GMT; path=/
Set-Cookie:=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/
Set-Cookie:GTRMAX=g4dhbh3tdkhql7m9iiovlvbqn3; expires=Wed, 03-May-2017 23:48:02 GMT; path=/
X-Powered-By:PHP/5.3.8

----------------------------

Servidor con PHP 5.5.27

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8
Connection:keep-alive
Cookie:GTRMAX=5iub8t5ba6fpt91651os441vs5
Host:hpartidas.webserver2a-local.sigis.com.ve
Referer:http://hpartidas.webserver2a-local.s..._pun_int=59025
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36

Response Headers

Cache-Control:must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive, close
Content-Disposition:attachment; filename=Apocalypse_starring_Bruce_Willis.jpg
Content-Length:24101
Content-Type:image/jpeg
Date:Thu, 04 May 2017 23:40:54 GMT
Expires:0
Pragma:public
Server:Apache/2.2.15 (CentOS)
Set-Cookie:GTRMAX=5iub8t5ba6fpt91651os441vs5; expires=Fri, 05-May-2017 01:40:54 GMT; Max-Age=7200; path=/
Set-Cookie:=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Set-Cookie:GTRMAX=5iub8t5ba6fpt91651os441vs5; expires=Fri, 05-May-2017 01:40:54 GMT; Max-Age=7200; path=/
X-Powered-By:PHP/5.5.27


Me pareció relevante dejar esta información, para ver si uds. ven algo en los headers que pueda estar afectando. Muchas gracias nuevamente.
__________________
Gmail : [email protected]
Twitter: @heiroon

I'm back!

Última edición por Heiroon; 04/05/2017 a las 13:46 Razón: Actualizando Info

Etiquetas: download, files, upload
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:57.