Foros del Web » Programando para Internet » PHP »

[SOLUCIONADO] Descarga de archivos mysql - archivo dañado

Estas en el tema de Descarga de archivos mysql - archivo dañado en el foro de PHP en Foros del Web. Buenos dias, estoy grabando documentos (docx, xlsx) en mysql (long bob) Este es el código de subida: Código PHP: $Doc_tmpname  =  $_FILES [ 'documento' ][ ...
  #1 (permalink)  
Antiguo 27/12/2018, 13:12
 
Fecha de Ingreso: diciembre-2001
Ubicación: Peru
Mensajes: 370
Antigüedad: 17 años, 1 mes
Puntos: 0
Descarga de archivos mysql - archivo dañado

Buenos dias, estoy grabando documentos (docx, xlsx) en mysql (long bob)
Este es el código de subida:
Código PHP:
$Doc_tmpname $_FILES['documento']['tmp_name'];  
$Doc_Tipo $_FILES['documento']['type']; 
$Doc_Nombre $_FILES['documento']['name'];
$Doc_Tamano $_FILES['documento']['size'];
$Doc_ext=pathinfo($Doc_NombrePATHINFO_EXTENSION);
$accion ="1";
$fp fopen($Doc_tmpname'r');
$contenido fread($fpfilesize($Doc_tmpname));
$contenido addslashes($contenido);
fclose($fp);
/*Grabamos Documento*/

if($Doc_ext=="png"||$Doc_ext=="PNG"||$Doc_ext=="JPG"||$Doc_ext=="jpg"||$Doc_ext=="jpeg"||$Doc_ext=="JPEG"
        
||$Doc_ext=="pdf"||$Doc_ext=="PDF"||$Doc_ext=="doc"||$Doc_ext=="DOC"||$Doc_ext=="docx"||$Doc_ext=="DOCX"
        
||$Doc_ext=="XLS"||$Doc_ext=="xls"||$Doc_ext=="XLSX"||$Doc_ext=="xlsx"||$Doc_ext=="xlsm"||$Doc_ext=="XLSM")


{
$Activo=1;
$grabadocumento $mysqli->prepare("INSERT INTO tb_documento (Nombre,Tipodoc,Fecha,Activo,Data,ID_Empresa,Size) VALUES ('$Doc_Nombre','$Doc_Tipo', '$Fecha','$Activo','$contenido','$ID_Empresa','$Doc_Tamano')");
$grabadocumento->execute(); 
$grabadocumento->close();

y este es el de descarga

Código PHP:
$ID_Documento $_GET['ID_Documento'];
$consulta "SELECT Nombre, Tipodoc, Data, Size FROM tb_documento WHERE ID_Documento=$ID_Documento";
$resultado=$mysqli->query($consulta);
$fila $resultado->fetch_assoc();
$Doc_data $fila['Data'];
$Doc_nombre $fila['Nombre'];
$Doc_tipo $fila['Tipodoc'];
$Doc_size $fila['Size'];

         
header("Content-length: $Doc_size");
         
header("Content-type: $Doc_tipe");
         
header("Content-Disposition: attachment; filename=$Doc_name");
       
ob_clean();
         
flush();
         echo 
$Doc_data;
         
$resultado->free();
         exit; 
El problema es que al descargarlo abre el archivo y sale este mensaje

"El archivo XXXXX.docx no puede abrirse porque hay problemas con el contenido"
Luego que se le da aceptar sale:
"Word encontro contenido no legible. ¿Desea recuperar el contenido de este documento?"
Le das aceptar y se abre, pero la idea es que esto no aparezca pues se ve mal.

Ya hice echo de los datos que trae desde la tabla y son estos:
$Doc_tipo= application/vnd.openxmlformats-officedocument.wordprocessingml.document
$Doc_size= 1530
$Doc_nombre= nombre.docx

Que podria ser?
uso PHP:7.0.15
y Mysql : 5.6.32

Saludos
  #2 (permalink)  
Antiguo 27/12/2018, 14:32
Avatar de alvaro_trewhela  
Fecha de Ingreso: octubre-2012
Ubicación: localhost
Mensajes: 949
Antigüedad: 6 años, 2 meses
Puntos: 109
Respuesta: Descarga de archivos mysql - archivo dañado

Totalmente desaconsejado usar motores de bases de dato como gestor de archivos, están hechos para guardar, valga la redundancia datos y no archivos, te recomiendo que guardes en la bd la dir del archivo y listo, pero si continuas con blobs lo que estás haciendo mal es usar

header("Content-length: $Doc_size");

doc_size no te esta dando el tamaño real del archivo en vez de usar $doc_size usa strlen($Doc_data);


Otra cosa cuidado con ese sql injection estas pasando un $_GET directo a la sentencia sql, te van a destruir la base de datos en menos de un parpadeo.
  #3 (permalink)  
Antiguo 27/12/2018, 16:06
 
Fecha de Ingreso: diciembre-2001
Ubicación: Peru
Mensajes: 370
Antigüedad: 17 años, 1 mes
Puntos: 0
Respuesta: Descarga de archivos mysql - archivo dañado

Muchas gracias por los consejos de seguridad, los tedré en cuenta.
Esta mejor asi?
<?php
$grabadocumento = $mysqli->prepare("INSERT INTO tb_documento (Nombre,Tipodoc,Fecha,Activo,Data,ID_Empresa,Size) VALUES (?,?,?,?,?,?,?)");
$grabadocumento->bind_param("sssisii", $Doc_Nombre,$Doc_Tipo,$Fecha,$Activo, $contenido, $ID_Empresa,$Doc_Tamano);
$grabadocumento->execute();
$grabadocumento->close();
php?>

Sobre grabar en la bd, lamentablemente no puedo guardar en el servidor, debe ser directo a la BD.

Aun asi no funciona
Gracias

Última edición por Murallitz; 27/12/2018 a las 16:41
  #4 (permalink)  
Antiguo 27/12/2018, 22:47
Avatar de alvaro_trewhela  
Fecha de Ingreso: octubre-2012
Ubicación: localhost
Mensajes: 949
Antigüedad: 6 años, 2 meses
Puntos: 109
Respuesta: Descarga de archivos mysql - archivo dañado

Te dejo una guía

file table

Código SQL:
Ver original
  1. CREATE TABLE files(
  2.     id INT NOT NULL AUTO_INCREMENT,
  3.     name VARCHAR(100) NOT NULL,
  4.     cont BLOB,
  5.     PRIMARY KEY(id)
  6. )

list.php

Código PHP:
Ver original
  1. <?php
  2.  
  3. $server = ["server"=>"localhost", "user"=>"root", "pass"=>"", "db"=>"test"];
  4.  
  5. $con = new mysqli($server["server"], $server["user"], $server["pass"], $server["db"]);
  6. if (!$con->connect_errno) {
  7. $q = $con->query("SELECT * FROM files");
  8.     if($q->num_rows > 0){
  9.     ?>
  10.     <table>
  11.         <tr>
  12.             <td>Name</td>
  13.             <td>Size</td>
  14.             <td>Link</td>
  15.         </tr>
  16.         <?php
  17.         while($file = $q->fetch_assoc()){
  18.         echo "<tr>";
  19.             echo "<td>".$file["name"]."</td>";
  20.             echo "<td>".round(strlen($file["cont"])/1024, 2)." Kb</td>";
  21.             echo "<td><a href=\"download.php?id=".$file["id"]."\">Download</a></td>";
  22.         echo "</tr>";
  23.         }
  24.         ?>
  25.     </table>
  26.     <?php
  27.     }
  28.     else{
  29.     echo "No files";
  30.     }
  31. }
  32. else{
  33. echo "DB ERROR";
  34. }
  35. ?>

download.php

Código PHP:
Ver original
  1. <?php
  2.  
  3. $server = ["server"=>"localhost", "user"=>"root", "pass"=>"", "db"=>"test"];
  4.  
  5. function my_is_int($i){
  6.     try{
  7.     intval($i);
  8.     return true;
  9.     }
  10.     catch(Exception $e){
  11.     return false;
  12.     }
  13. }
  14.  
  15. $id = -1;
  16. if(isset($_GET["id"]) && my_is_int($_GET["id"])) $id = intval($_GET["id"]);
  17.     if($id != null){
  18.     $con = new mysqli($server["server"], $server["user"], $server["pass"], $server["db"]);
  19.         if (!$con->connect_errno) {
  20.         $q = $con->query("SELECT * FROM files WHERE id=$id");
  21.             if($q->num_rows > 0){
  22.             $file = $q->fetch_assoc();
  23.             header("Content-Type: application/octet-stream");
  24.             header("Content-Transfer-Encoding: Binary");
  25.             header("Content-disposition: attachment; filename=\"" .$file["name"]. "\"");
  26.             header("Content-length: ".strlen($file["cont"]));
  27.             echo $file["cont"];
  28.             exit();
  29.             }
  30.         }
  31.     }
  32. echo 0; //send a 0 if some error...
  33. ?>

upload.php

Código PHP:
Ver original
  1. <?php
  2.  
  3.  
  4. function myfread($file){
  5.     if(file_exists($file)){
  6.     $fo = fopen($file,"r");
  7.     $cnt = fread($fo, filesize($file));
  8.     fclose($fo);
  9.     return $cnt;
  10.     }
  11. return "";
  12. }
  13.  
  14. $server = ["server"=>"localhost", "user"=>"root", "pass"=>"", "db"=>"test"];
  15.  
  16. $con = new mysqli($server["server"], $server["user"], $server["pass"], $server["db"]);
  17. if (!$con->connect_errno) {
  18.     if(isset($_FILES["file"])){
  19.     $f = $_FILES["file"];
  20.     $st = $con->prepare("INSERT INTO files (name, cont) VALUES (?, ?)");
  21.     $st->bind_param("ss", $f["name"], myfread($f["tmp_name"]));
  22.         if ($st->execute())
  23.             echo "uploaded";
  24.         else
  25.             echo "some error occurred";
  26.     }
  27.     else{
  28.     ?>
  29.     <form method="post" action="" enctype="multipart/form-data">
  30.     <input type="file" name="file"/><input type="submit" value="upload" />
  31.     </form>
  32.     <?php
  33.     }
  34. }
  35. else{
  36. echo "DB ERROR";
  37. }
  38. ?>



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