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 :

Requête préparée via PDO


Sujet :

PHP & Base de données

  1. #1
    Candidat au Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut Requête préparée via PDO
    Bonjour à tous !

    Je suis actuellement en train de créer une application pour faire de l'importation de fichier dans une base avec quelques contraintes. Je voudrai mettre en place une requête préparer pour un gain de ressource, et ce avec PDO. Je suis totalement novice et je ne connais que peu de chose sur PDO.
    Enfin je pense que mon code vous parlera plus qu'un long discours. Donc voila le morceau de script me posant problème..

    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
    18
    19
    20
    	$connexion = new PDO('mysql:host='.$host.';dbname='.$bd, $user, $mdp);
    	$Insert = "INSERT INTO data (";
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= $champsBd[$i].", ";
    	}
    	$Insert .= $champsBd[$i].") VALUES(";
     
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= "?, ";
    	}
    	$Insert .= "?)"; 
    	//echo $Insert;
     
    	$reqPrepare = $connexion->prepare($Insert);
     
    	for($j=0;$j<count($dataChamps);$j++) {
    		//echo $champsBd[$j];
    		$reqPrepare->bindParam($j, $dataChamps[$j]);
    		$reqPrepare->execute();
    	}
    Le code est totalement buger et surement très incohérent...
    Merci de vos réponses .

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Je n'ai pas testé mais ca devrait bien marcher.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $connexion = new PDO('mysql:host='.$host.';dbname='.$bd, $user, $mdp);
    	$Insert = "INSERT INTO data (" . implode(",", $champBd) . ") 
                           VALUES (" .  str_repeat("?,", count($champBd) -1 . "?)";
    	$reqPrepare = $connexion->prepare($Insert);
    	$reqPrepare->execute($dataChamps);
    Bien entendu tu ne reprepares pas la requete a chaque execution sinon ca n'a plus d'interet.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Candidat au Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Effectivement j'ai passé certains points sous silence... Je ne prépare pas ma requête à chaque fois, c'est seulement que je constitue la syntaxe de ma requête à l'aide d'une boucle. En faite je fait de l'insertion de fichiers CSV dans ma base de données. Seulement je ne ne me sert pas de tout les colonnes dans les différents CSV que j'importe, et je doit absolument vérifier les entête des fichiers CSV pour m'assurer que le nom de la colonne n'a pas été modifier.

    Donc du coté SGBD, j'ai une table 'champs' et une table 'data'. La table 'data' contient 26 champs ( le fichier CSV en contient 146 et je n'ai besoin donc que des 26). La table 'champs' contient elle 2 champs, un champs 'nomColonneBd' qui contient les différents nom de champs de ma table 'data' et enfin le champs 'nomcolonneCsv' qui contient les noms des entêtes CSV qui m'intéressent. C'est donc grâce à cette table 'champs' que je vérifie la cohérence de mes données.

    Je me retrouve donc avec deux fonctions, une première qui lit l'entête de mon fichier CSV puis la deuxième qui s'occupe du contenu, et ces deux fonctions me renvoi un array. Aussi les valeurs de la requête changent à chaque 'INSERT'.

    Je vous poste ici mon code complet d'insertion dans ma base ainsi que ma fonction qui se charge de lire le fichier CSV. Merci a vous et désolé de mes grand discours .

    @sabotage: Merci de ta réponse .


    Page d'insertion:

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    <?php
    include('header.php');
    $dest = "./CSV/"; //Repertoire de destination
    $erreur = 0; //init du nb d'erreurs
    $mimeUp = $_FILES['fichier']['type']; //Type mime du fichier upload
    $mimeValide = "application/vnd.ms-excel"; //Type mime autorisé
    $nomFichierUp = $_FILES['fichier']['name']; //Nom du fichier upload
    $genereNom = md5(uniqid(rand(), true)); // Genere une chaine aléatoire
     
    if($mimeUp != $mimeValide) { //Verif du Mime
    	$erreur++;
    	$erreur1 = "Erreur le fichier n'est pas de type CSV.";
    }
     
    if($_FILES['fichier']['error'] > 0) { //Verif erreur d'upload.
    	$erreur++;
    	$erreur2 = "Erreur lors du transfert.";
    }
     
    if($_FILES['fichier']['size'] > $_POST['MAX_FILE_SIZE']) { //Verif de la taille du fichier
    	$erreur++;
    	$erreur3 = "Le poids du fichier dépasse la limite autorisé.";
    }
     
    if(preg_match('#[\x00-\x1F\x7F-\x9F/\\\\]#', $nomFichierUp)) { //Verif des caractère autorisé
    	$erreur++;
    	$erreur4 = "Le nom du fichier n'est pas valide.";
    }
     
    if($erreur != 0) { //Affichage des erreurs pendant l'upload....
    	echo ' Des erreurs on été trouver, '.$erreur.' au total. Les voici: <br />
    	'.$erreur1.'<br />
    	'.$erreur2.'<br />
    	'.$erreur3.'<br />
    	'.$erreur4.' ';
    	exit;
    }
     
    if($erreur == 0) { //Si il n'y pas d'erreur pendant l'upload, le traitement peut continuer.
     
    	$nomFichierFinal = $genereNom."majCsv.csv"; //Génere un nom unique pour le fichier upload.
    	move_uploaded_file($_FILES['fichier']['tmp_name'], $dest . $nomFichierFinal); //On déplace le fichier dans le repertoire de destination.
     
    	include('fonctions/fonctionLireCsv.php'); //Fonction qui lit le CSV.
    	include('config/config.php'); //Fichier de config ( cnx base de données ect ..)
    	include('fonctions/fonctionParseCsv.php'); //Fonction pour parser le contenu du cSV
     
    	$enTeteCsv = lectureEnteteCsv($separateur, $dest); //Fonction qui lit l'entete du CSV.
    	$contenuCsv = lectureContenuCsv($separateur, $dest); //Fonction qui lit le contenu du CSV.
     
    	$req = mysql_query('SELECT nomColonneCsv, nomColonneBd FROM champs'); // On liste les champs du fichiers CSV selon la config de la base de données.
    	while($res = mysql_fetch_array($req)) { 
    		$champsCsv = $res['nomColonneCsv'];
    		$champsBd[] = $res['nomColonneBd'];
    		if(array_search($champsCsv, $enTeteCsv) === false){ //Verification que les champs du fichiers CSV n'ont pas été modifiés.
    			echo 'Le fichier Csv à été modifier, veuillez le configurer correctement.';
    			exit;
    		}
    		$key[] = array_search($champsCsv, $contenuCsv[0]); // Creation du tableau qui va contenir les clé recherchés.
    	}
     
    	for($i=1;$i<count($contenuCsv);$i++) { //Génération des array qui vont contenir les données du fichiers CSV.
    		for($j=0;$j<count($key);$j++) {
    			if($contenuCsv[$i][$key[$j]] == "") { // Si le contenu du champs est vide, la chaine de caractère "NC" est attribué au champs.
    				$dataChamps[] ="NC";	
    			}
    			else {
    				$dataChamps[] = $contenuCsv[$i][$key[$j]]; //Sinon la valeur du champs est stocker dans le tableau.
    			}
    		}	
    	}
     
     	$host = 'localhost';
    	$user = 'root';
    	$mdp = '';
    	$bd = 'test';
     
    	$connexion = new PDO('mysql:host='.$host.';dbname='.$bd, $user, $mdp);
    	$Insert = "INSERT INTO data (";
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= $champsBd[$i].", ";
    	}
    	$Insert .= $champsBd[$i].") VALUES(";
     
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= "?, ";
    	}
    	$Insert .= "?)"; 
    	//echo $Insert;
     
    	$reqPrepare = $connexion->prepare($Insert);
     
    	for($j=0;$j<count($dataChamps);$j++) {
    		//echo $champsBd[$j];
    		$reqPrepare->bindParam($j, $dataChamps[$j]);
    		$reqPrepare->execute();
    	}
    }
     
    include('footer.php');
    ?>
    Et enfin les deux fonctions qui lise le fichier CSV:

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <?php
    function lectureEnteteCsv($separateur, $dest) { // Fonction qui lit l'entête du CSV.
     
    	$ouverture = opendir($dest);
    		while(false !== ($fichier = readdir($ouverture))) {
    			if ($fichier != "." AND $fichier != "..") {
    				$file = fopen($dest."/".$fichier, "r");
    			}
    		}
    		closedir($ouverture);
     
    	$arrayEnTete = array();
    	$arrayEnTete = fgetcsv($file, 0, $separateur);
    	fclose($file);
    	return $arrayEnTete;
    }
     
    function lectureContenuCsv($separateur, $dest) { // Fonction qui lit le contenu du CSV 
     
    	$ouverture = opendir($dest);
    		while(false !== ($fichier = readdir($ouverture))) {
    			if($fichier != "." AND $fichier != "..") {
    				$file = fopen($dest."/".$fichier, "r");
    			}	
    		}
    		closedir($ouverture);
     
    	while(!feof($file)) {
    		$arrayContenu[] = fgetcsv($file, 0, $separateur);
    	}
     
    	fclose($file);
    	return $arrayContenu;
    }
    ?>
    Voila !

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Quelle est la question ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Candidat au Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Et bien c'est que ma requête est incorrecte, elle plante et son exécution me renvoi une erreur. Je ne passe pas correctement les valeur à bindParam. Donc mes marqueurs ne sont pas correcte.

    1ier cas de figure, j'enregistre mes marqueurs dans ma table, 2ième cas, mes données s'enregistre ( une ligne seulement ), et de manières décalé au niveau des champs.

    Je voudrai donc quelques conseils pour aborder l'écriture de ma requête au mieux.

  6. #6
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    ce que je t'ai proposé ne fonctionne pas ?
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  7. #7
    Candidat au Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Non sa ne fonctionne pas .. $dataChamps est un array .. J'ai tester donc l'exécute dans une boucle mais sa ne fonctionne pas non plus.. je vous montre les message d'erreurs:

    pour ce code la :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	$connexion = new PDO('mysql:host='.$host.';dbname='.$bd, $user, $mdp);
     
     
    	$Insert = "INSERT INTO data (" . implode(",", $champBd) . ") 
                           VALUES (" .  str_repeat("?,", count($champBd) -1 . "?)";
    	$reqPrepare = $connexion->prepare($Insert);
    	$reqPrepare->execute($dataChamps);
    j'obtient :

    Fatal error: Call to a member function execute() on a non-object in C:\wamp\www\statech\traitementImportCsv.php on line 91

    Et enfin pour ce code la :

    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
    18
    19
    20
    	$Insert = "INSERT INTO data (";
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= $champsBd[$i].", ";
    	}
    	$Insert .= $champsBd[$i].") VALUES(";
     
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= "?, ";
    	}
    	$Insert .= "?)"; 
    	echo $Insert;
     
    	$reqPrepare->execute($dataChamps);
     
    	$reqPrepare = $connexion->prepare($Insert);
     
    	for($j=0;$j<26;$j++) {
    		echo $champsBd[$j];
    		$reqPrepare->execute($dataChamps);
    	}
    j'obtient le même message d'erreur que celui que j'ai mit plus haut .

  8. #8
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    $dataChamps est un array
    Le paramètre d'execute EST un array contenant les valeurs.
    http://fr.php.net/manual/fr/pdostatement.execute.php

    Il manquait par contre une parenthese dans mon $Insert :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	$Insert = "INSERT INTO data (" . implode(",", $champBd) . ") VALUES (" .  str_repeat("?,", count($champBd) -1) . "?)";
    	$reqPrepare = $connexion->prepare($Insert);
    	$reqPrepare->execute($dataChamps);
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  9. #9
    Candidat au Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Je suis vraiment trop idiot des fois .. Sa fonctionne correctement, enfin presque !

    J'ai donc réussi à insérer la première ligne de mon fichier CSV en utilisant ce bout de code :

    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
    18
    	$connexion = new PDO('mysql:host='.$host.';dbname='.$bd, $user, $mdp);
    	$Insert = "INSERT INTO data (";
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= $champsBd[$i].", ";
    	}
    	$Insert .= $champsBd[$i].") VALUES(";
     
    	for($i=0;$i<count($key) -1;$i++) {
    		$Insert .= "?, ";
    	}
    	$Insert .= "?)"; 
    	echo $Insert;
    	$reqPrepare = $connexion->prepare($Insert);
     
    	for($j=0;$j<26;$j++) {
    		$dat[] = $dataChamps[$j];
    	}
    	$reqPrepare->execute($dat);
    Seulement mon array $dataChamps contient un nombre variable de clé. Et je doit bien évidemment insérer 27 champs dans ma table 'data' qui ne contient que .... 27 champs

    Donc comment reconstituer mon nouvel array $dat pour qu'il parte de 0 a 26 puis de 28 à 55 ect ... Je ne voudrai pas faire de boucle plus qu'il n'en faut... Mon code est déjà assez sale

Discussions similaires

  1. [TinyMCE] Requête préparée pdo
    Par Invité dans le forum Bibliothèques & Frameworks
    Réponses: 4
    Dernier message: 12/03/2014, 20h29
  2. [PDO] Requête préparée PDO
    Par ben256xp dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 03/06/2013, 09h47
  3. [MySQL] Problème de requête préparée avec PDO
    Par fab56 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 16/01/2013, 22h06
  4. [PDO] PDO PHP-POO et requêtes préparées
    Par distar dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 06/01/2012, 19h04
  5. [PDO] Problème de requête préparée (à n'y rien comprendre?)
    Par waldo2188 dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 20/03/2007, 21h53

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