IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Quel format de données pour insérer un pdf dans un champ BLOB ? [SQL-Server]


Sujet :

PHP & Base de données

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut Quel format de données pour insérer un pdf dans un champ BLOB ?
    Bonjour,

    dans le cadre d'un projet php, il m'est imposé de coder cette opération.
    (Pour avoir fait de nombreuses recherches sur les champs blob, je sais que cela n'est pas conseillé mais ce n'est pas moi qui décide.)

    J'arrive à récupérer le contenu du champ et à recomposer un pdf valide, mais pour l'opération d'insertion je n'y parviens pas.


    Environnement : PHP + SQL SERVER

    Voici la fonction qui exécute la requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public function updateDocument($idDocument, $content) {
     
        //$req = "UPDATE DOCUMENTS SET BLOB = (SELECT BULKCOLUMN FROM OPENROWSET(BULK 'documents/marge.pdf', SINGLE_BLOB) AS I) WHERE ID_DOCUMENT = $idDocument";
        $req = "UPDATE DOCUMENTS SET BLOB = '$content' WHERE ID_DOCUMENT = $idDocument";
     
        $res = ConnectionDb::$myPdo->exec($req);
        return $res;
    }
    Comme vous pouvez voir j'ai testé deux requetes différentes car bulk fonctionnait sous un autre projet en vb.net mais ici c'est différent et cela ne fonctionne pas.
    Le fichier se trouve sur le serveur wamp local pour le développement, dans le répertoire du site, et je n'ai pas mis le chemin complet depuis C:\ car il faudrait qu'il soit trouvé quelque soit le type de serveur.

    La deuxième requete me parait être la plus indiquée mais je bute sur le format de données à envoyer.
    Pour la réception de fichier il s'agit d'une chaine en hexadécimal, mais quand j'effectue l'update avec la nouvelle chaine en hexa, cela stocke simplement une chaine en hexa dans le blob et non un pdf valide.
    J'ai cherché partout et testé différents types mais pas de résultat..*

    Auriez vous la réponse svp ?

  2. #2
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    je m'aperçois que lorsque j'envoie la chaine en hexadecimal dans le blob, le résultat visible avec SQL management studio, est une chaine en décimal alors que les pdf envoyés par mon application VB.net avec openrowset (et valides) affichent une chaine en hexadecimal...

    lorsque j'envoie les données sans conversion, à la sortie de la fonction php "file_get_contents" , ça ne fonctionne pas je pense à cause de tous les caractères spéciaux, et si j'essaye de les enlever avec d'autres fonctions le fichier n'est pas bon non plus...

    je m'arrache les cheveux ^^

  3. #3
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    as-tu essayé d'échapper $content avant insertion ?
    Un truc du genre : $pdo->quote($content);ou carrément utiliser une requête préparée ?

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Merci de bien vouloir m'aider.

    Pour l'échappement j'ai tenté cette requete :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $req = "UPDATE DOCUMENTS SET BLOB = '".ConnectionDb::$myPdo->quote($content)."' WHERE ID_DOCUMENT = $idDocument";
    Cela n'a pas fonctionné. Est-elle correcte?


    Pour ta deuxième proposition je ne sais pas trop encore en quoi cela consiste, je vais me pencher dessus..

  5. #5
    Membre éprouvé Avatar de Willy_k
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 540
    Points : 1 067
    Points
    1 067
    Par défaut
    Salut, que contient $content ?
    Tu parles de chaîne hexa mais comment tu l'obtiens cette chaîne là ?
    Tu peux aussi regarder ici http://php.net/manual/fr/pdo.lobs.php tu pourra avoir sûrement des pistes
    Le bienfait n'est jamais perdu

  6. #6
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 691
    Points : 20 222
    Points
    20 222
    Par défaut
    Un blob attends un contenu binaire.
    Donc ton $content devrait le contenu de ton pdf obtenu par exemple avec $content = file_gets_content('monfichier.pdf') .
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Bonjour et merci à tous.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $fluxBinaire = file_get_contents("documents/marge.pdf");
     
    $fluxHex = bin2hex($fluxBinaire);
     
    $fluxHexMaj = strtoupper($fluxHex);
    Hier, j'ai tenté sans succès avec ces trois variables pour $content, avec les deux requetes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $req = "UPDATE DOCUMENTS SET BLOB = '$content' WHERE ID_DOCUMENT = $idDocument";
    $req = "UPDATE DOCUMENTS SET BLOB = '".ConnectionDb::$myPdo->quote($content)."' WHERE ID_DOCUMENT = $idDocument";
    Avec $fluxBinaire aucune des deux requetes ne passe et la base n'est pas mise à jour.
    Avec les deux autres variables, la base est mise à jour (requete 1) mais le contenu du champ est donc une chaine et non un pdf.


    @Willy_k
    En suivant ton conseil, voici les deux fonctions que j'ai testées ce matin (insertion cette fois ci pour ne pas trop déroger à l'exemple donné dans le lien) :
    (avec et sans realpath)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public function testBlob() {    
     
    $stmt = ConnectionDb::$myPdo->prepare("insert into DOCUMENTS (BLOB, ID_TYPEDOCUMENT) values (?, ?)");
     
    $path = realpath("documents/marge.pdf");
    $fp = fopen($path, 'rb');
     
    $stmt->bindParam(1, $fp, PDO::PARAM_LOB);
    $stmt->bindValue(2, 'FE');
     
     
    ConnectionDb::$myPdo->beginTransaction();
    $stmt->execute();
    ConnectionDb::$myPdo->commit();
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function testBlob2() {    
     
    $stmt = ConnectionDb::$myPdo->prepare("insert into DOCUMENTS (BLOB, ID_TYPEDOCUMENT) values (?, ?)");
     
    $data = file_get_contents("documents/marge.pdf");
    $stmt->bindParam(1, $data, PDO::PARAM_LOB);
    $stmt->bindValue(2, 'FE');
     
    ConnectionDb::$myPdo->beginTransaction();
    $stmt->execute();
    ConnectionDb::$myPdo->commit();
     
    }
    Malheureusement il ne se passe strictement rien..pas d'erreur mais pas d'insertion et chargement de la suite bien trop rapide..

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Attention aux mots réservés du SQL.

    BLOB en fait partie.

    Si ton champ s'appelle BLOB, il faut l'échapper dans les requêtes :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "insert into DOCUMENTS ('BLOB', ID_TYPEDOCUMENT) values (?, ?)"
     
    "UPDATE DOCUMENTS SET 'BLOB' = ...........

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Merci pour l'information mais avec l'echappement la requete ne passe pas et du coup j'ai créé pour les tests une nouvelle table avec un autre nom de champ, mais les résultats sont les mêmes..

  10. #10
    Invité
    Invité(e)
    Par défaut
    OK. Il faut remplacer le ' par des ` (touches AltGr + 7 du clavier)
    Mais bon. A priori, ce n'est pas ça qui pose problème dans ton cas...

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Ok merci

    Mais concrètement, même si ce n'est pas la meilleure solution, c'est quelque chose de faisable avec php puisque c'est même prévu avec PDO.
    Il reste à trouver ce qui cloche..

    Ce qui est bizarre avec ces requetes préparées, c'est que le chargement est ultra-rapide comme si l'opération n'était même pas tentée..

  12. #12
    Membre éprouvé Avatar de Willy_k
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 540
    Points : 1 067
    Points
    1 067
    Par défaut
    Salut, As-tu activé les erreurs au niveau de ta connexion ?
    Le bienfait n'est jamais perdu

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    si tu fais référence aux erreurs php oui je pense que j'ai l'affichage de toutes les erreurs.
    J'utilise Wamp + Netbeans et quand j'ai une erreur php elle s'affiche avec le point d'exclamation, la phrase d'explication, les variables...Etc.
    Et dans php.ini j'ai bien "error_reporting = e_all"

    Concernant les requêtes sql qui n'ont pas l'effet escompté, je n'ai pas de message d'erreur par contre.
    Je le vois ensuite en rafraichissant l'affichage de la table.

  14. #14
    Membre éprouvé Avatar de Willy_k
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2011
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2011
    Messages : 540
    Points : 1 067
    Points
    1 067
    Par défaut
    Non au niveau de ta connexion, juste après new PDO() par exemple donc suivant ton script avoir un truc comme ça self::$myPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); dans ta classe ConnectionDb,
    dans ce cas s'il y'a des des soucis au niveau de ta requête, tu auras un retour
    Le bienfait n'est jamais perdu

  15. #15
    Invité
    Invité(e)
    Par défaut
    Bon.

    Je viens de tester :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $file = 'documents/xxx.pdf';
    $data = file_get_contents($file);
    $idtype = '2';
     
    $stmt = $pdo->prepare("INSERT into DOCUMENTS (`blob_pdf`, ID_TYPEDOCUMENT) values (:data, :idtype)");
    $stmt->bindParam(':data', $data, PDO::PARAM_LOB);
    $stmt->bindParam(':idtype', $idtype, PDO::PARAM_INT);
    $stmt->execute();
    ré-affichage du fichier :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="affiche-pdf.php?id=1">PDF 1</a>
    affiche-pdf.php :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <?php
    header('Content-type:PDF; charset=UTF-8');	// encodage UTF-8
    // -----------------------------------------------
    	require (__DIR__.'/_test_connexion/_config_connexion_pdo.php'); 
    // -----------------------------------------------
    $id = ( !empty($_GET['id']) )? intval($_GET['id']) : 0;
    if( $id == 0 ){ exit; }
     
    $stmt = $pdo->prepare("SELECT `blob_pdf` FROM DOCUMENTS WHERE id = :id");
    $stmt->bindValue(':id', $id, PDO::PARAM_INT);
    $stmt->execute();
    $row = $stmt->fetch();
     
    $pdf = $row['blob_pdf'];
    echo $pdf;

    Ca fonctionne parfaitement.

    Donc, ce n'est pas cette partie qui pose problème.


    [EDIT] Pour gérer les erreurs de requêtes : Les erreurs et leur gestion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    try {
     
    	$stmt = $pdo->prepare("INSERT into DOCUMENTS (`blob_pdf`, ID_TYPEDOCUMENT) values (:data, :idtype)");
    	$stmt->bindParam(':data', $data, PDO::PARAM_LOB);
    	$stmt->bindParam(':idtype', $idtype, PDO::PARAM_INT);
    	$stmt->execute();
    }
    catch(PDOException $e){
    	$msg = 'ERREUR PDO dans ' . $e->getFile().' L.' . $e->getLine().' : ' . $e->getMessage();
    	die($msg);
    }
    Dernière modification par Invité ; 26/04/2017 à 14h02.

  16. #16
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Ben mince chez moi ça ne fonctionne pas, il n'y a ni message d'erreur ni insertion.
    Il y a quelque chose qui cloche dans le code?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public function testBlob5() {    
     
        $file = 'documents/marge.pdf';
        $data = file_get_contents($file);
        $idtype = '2';
     
        $stmt = ConnectionDb::$myPdo->prepare("INSERT into TESTS (DOCPDF, ID) values (:data, :idtype)");
        $stmt->bindParam(':data', $data, PDO::PARAM_LOB);
        $stmt->bindParam(':idtype', $idtype, PDO::PARAM_INT);
        $stmt->execute();
    }
    La fonction est placée dans la classe du pdo et cela fonctionne pour toutes les autres fonctions manipulant les autres types de données, telle que celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public function insertSuivre($idAction, $idContact) {
     
        $req = "INSERT INTO SUIVRE (ID_ACTION, ID_CONTACT) VALUES ($idAction, $idContact)";
        $res = ConnectionDb::$myPdo->exec($req);
    }

  17. #17
    Invité
    Invité(e)
    Par défaut
    1/ Dans ta table TESTS, on est d'accord que "ID" n'est pas l'index auto-incrémenté ?

    2/ Ajoute la gestion d'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public function testBlob5() {    
    	$msg = '';
        $file = 'documents/marge.pdf';
        $data = file_get_contents($file);
        $idtype = '2';
     
      try {
       $stmt = ConnectionDb::$myPdo->prepare("INSERT into TESTS (DOCPDF, ID) values (:data, :idtype)");
        $stmt->bindParam(':data', $data, PDO::PARAM_LOB);
        $stmt->bindParam(':idtype', $idtype, PDO::PARAM_INT);
        $stmt->execute();
      }
      catch(PDOException $e){
    	$msg = 'ERREUR PDO dans ' . $e->getFile().' L.' . $e->getLine().' : ' . $e->getMessage();
      }
    	return $msg;
    }
    ensuite
    3/ As-tu essayé SANS mettre le code dans une fonction ?

  18. #18
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    1/ oui ID est juste une colonne Int sans contraintes sans index

    2/ c'est fait et toujours aucune erreur ni message lors du test

    3/ du coup je viens de le faire (avec $myPdo en public au lieu de privé) mais ça n'a rien changé


    La connexion à la base de données est valide c'est certain puisque j'ai un test avec affichage du résultat à chaque lancement.
    Toujours aucune insertion dans la base..

  19. #19
    Invité
    Invité(e)
    Par défaut
    Pas mieux...

  20. #20
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 16
    Points : 2
    Points
    2
    Par défaut
    Merci de votre aide à tous en tout cas.

    Si chez toi ça fonctionne, ça pourrait peut-être venir de ma configuration?

    J'ai installé ces dll dans le dossier ext :

    php_sqlsrv_56_ts.dll
    php_pdo_sqlsrv_56_ts.dll avec ajout de l'extension dans php.ini

    Ou alors peut-être que ça vient de php.ini pour une autre raison...je ne suis pas assez calé dans tout ça...
    Le pdo fonctionne pour tout le reste mais du coup impossible de charger un objet comme on tente de le faire actuellement..

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 11
    Dernier message: 11/07/2014, 11h47
  2. Réponses: 4
    Dernier message: 12/07/2010, 19h48
  3. quel etl peut faire ca : charger un pdf dans une colonne BLOB
    Par sulfurex dans le forum Alimentation
    Réponses: 0
    Dernier message: 09/04/2010, 10h01
  4. Comment fait-on pour insérer une date dans un champs DateTime
    Par gibea00 dans le forum Accès aux données
    Réponses: 1
    Dernier message: 14/01/2007, 01h04
  5. Probléme pour insérer une variable dans un champs
    Par BOUTRAIS dans le forum Access
    Réponses: 2
    Dernier message: 11/04/2006, 22h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo