Page 1 sur 2
LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 07:45
par morhead
En gros j'ai un champ blob (image) en base contenant tous mes ficheirs.
Je veux via un header générer le fichier sans le stocker.
Mon code:
Code : Tout sélectionner
header("Content-Type: $ctype" );
//header("Content-type: application/force-download");
header("Content-Disposition: attachment; filename=$file");
header("Content-Description: File Transfert" );
header("Content-Transfer-Encoding: binary" );
header("Pragma: no-cache" );
header('Content-Length: ' . filesize($file));
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header("Expires: 0" );
ob_clean();
flush();
echo $recupere_doc['Contenu_Doc'];
J'ai effectué plusieurs tests.
En utilisant un fopen , j'ai créé le fichier puis rempli avec le contenu du champ image.
J'ai testé plusieurs méthodes et le résultat est le même...
Fichier corrompu dès qu'il y a une mise en forme, sur un texte .txt simple ca passe.
Que faire ?
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 09:34
par Mazarini
Bonjour,
Il faut utiliser un stockage binaire (interclassement ?) sur la base de données ou sur la table. En gros, il est possible que lors des manipulations de maj ou de lecture des octets du contenu soit modifié.
Pour tester, utilise une petite image et stocke sont contenu en base et créer un fichier à partir de la base. Tu pourras alors voir si le contenu est modifié en comparant les 2 fichiers.
Je ne peux malheureusement pas plus t'aider. En général, on évite de stocker des images en base. On stocke plutôt dans des fichiers et on garde uniquement le moyen de récupérer l'image dans la base.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 09:51
par morhead
Le stockage est même pire que ça puisque dans le champ de type image sont stockés tous les fichiers (pdf, excel,etc...) mais c'est pas moi qui décide ^^
Avec un soft développé en Delphi, les fichiers ressortent bien.
Il n'y a aucun traitement dans le code juste un ExtractFilePath puis TBlobField(FieldByName('Contenu_Doc')).SaveToFile(sPath);
A noter c'est sur SQL Server.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 10:07
par Mazarini
Tu peux remplacer echo $recupere_doc['Contenu_Doc']; par readfile('un fichier');
Pour voir si ca marche avec le contenu d'un fichier.
Tu peux également vérifier le contenu recu avec un éditeur en enregistrant le contenu dans un fichier. Pas impossible qu'ob_clean() et flush() ne laisse pas passer des caractères en début ou fin.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 10:27
par morhead
Je viens de tester j'ai un fichier pdf sur le serveur, quand j'essaie de l'ouvrir via le read le fichier est corrompu encore...Si je l'ouvre sur le serveur manuellement pas de soucis...
Cela vient de l'apache ??
A noter le fichier sur le serveur fait 13Ko et sur le poste client une fois enregistré il fait 52Ko...
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 10:53
par Mazarini
Pour moi, ca vient de ob_clean() et flush().
Il doit y avoir des caractères qui sont quand même envoyé :
- message d'erreur PHP ou mysql ?
- saut de ligne ?
C'est ce qui pose problème généralement avec les images en général donc aussi avec des fichiers word ou pdf.
Supprimes l'envoi de l'image pour voir si quelque chose est envoyé en plus. A savoir, ob_end_clean() vide le buffer alors que ob_clean() j'ai un doute. Mais on ne voit pas d'ob_start() dans l'extrait de ton script.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 11:05
par morhead
Petite question quand je fais l'echo de mon contenu d'un docx à l'affichage j'ai (juste un morceau) :
Code : Tout sélectionner
PK!¬†PWŽÀ[Content_Types].xml ¢( ´”ËNÃ0E÷HüCä-Jܲ@5íÊ*QÄÚ8“Ö"~Èã¾þžqQ[µM¡°‰”Ø÷Þ3{:½¹®’)xTÖ䬵XFÚB™QÎÞ‡Ïé=K0SˆÊÈÙõº×WáÂ&¤6˜³qîs”cÐ3ëÀÐJi½^ýˆ;!¿Äøm«uÇ¥5LHCô`ÝΔbR…¤?§Ï+gF,y\í‹Q9S:êãw~Pá¡Â=‰p®RRªOM±Ç•®™2R.÷àX9¼!ð# qe
Cela me semble bizarre...
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 11:25
par morhead
J'ai oublié de dire que les fichiers .log donc qui s'ouvrent dans le bloc note fonctionnent sans probleme.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 11:52
par Mazarini
1) Cherche de caractère parasite :
echo '[debut]';
echo $recupere_doc['Contenu_Doc'];
echo '[fin]';
Pour voir s'il y a quelque chose avant ou après le contenu de ton fichier log.
ou
2) Contrôle du contenu
echo $recupere_doc['Contenu_Doc'];
$f = fopen('fichier.xxx','w');
fwrite($f,$recupere_doc['Contenu_Doc']);
fclose($f);
Pour voir si fichier.xxx est bien formater (avec un docx ou autre en adaptant xxx) et s'ouvre bien
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 12:01
par morhead
Bon j'avance....j'arrive à afficher un docx maintenant en faisant un readfile, par contre l'echo toujours le même problème...
Code : Tout sélectionner
$file = $recupere_doc['Nom_Doc'];
ob_start();
header("Content-Type: $ctype" );
header("Content-Disposition: attachment; filename=$file");
header("Content-Transfer-Encoding: binary" );
header("Pragma: public" );
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" );
header("Expires: 0" );
echo $recupere_doc['Contenu_Doc'];
ob_flush();
flush();
ob_end_clean();
Mon code a un problème c'est pas possible !
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 12:03
par morhead
Sur le docx il ne m'affiche pas debut et fin
Sur le serveur j'ai le même soucis le fichier est corrompu.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 12:15
par morhead
Pour résumer :
Si un fichier docx présent sur le serveur : affichage ok avec readfile()
Si on affiche le champ blob via un header/echo : erreur fichier corrompu, le texte est présent mais pas d'images.
Si je génère un fichier docx/pdf avec un fopen/fwrite : erreur fichier corrompu, le texte est présent mais pas d'images.
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 13:30
par Mazarini
Si je génère un fichier docx/pdf avec un fopen/fwrite : erreur fichier corrompu, le texte est présent mais pas d'images.
Pour moi, ca veut dire qu'il se passe quelque chose lors de la récupération de $recupere_doc['Contenu_Doc']. Comme cela marche avec delphi, je suppose que le stockage es ok et que c'est la lecture qui merde.
Comment fais tu la lecture ?
Tu peux regarder :
PDO::SQLSRV_ENCODING_BINARY (entier)
Spécifie que cette donnée est envoyée vers le (ou reçue du) serveur comme un flux d'octets, sans opérer d'encodage ou de traduction. Cette constante peut être utilisée dans les appels à PDOStatement::setAttribute, PDO::prepare, PDOStatement::bindColumn, et PDOStatement::bindParam.
source :
http://php.net/manual/fr/ref.pdo-sqlsrv.php
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 13:35
par morhead
Tu as la meme chose avec mssql ? ^^
Je récupère comme cela :
Code : Tout sélectionner
$recup_doc="SELECT * from table WHERE ID_Doc='$get_doc'";
$req_doc= mssql_query($recup_doc,$dblink) or die(mssql_error());
while($recupere_doc=mssql_fetch_assoc($req_doc)){
(instructions header)
}
Re: LONGBLOB en fichier sans stockage intermédiaire
Posté : 24 juin 2013, 14:07
par morhead
Oui cela doit venir de la, en base c'est en binaire et quand je fais un echo des fichiers docx/pdf et autres (sauf .log/.txt, ) je n'ai pas la même que que ce qu'il y a en base...
Je n'utilise pas PDO et arrivé au point ou j'en suis du dev (je continue un pré existant) je ne peux pas changer.