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 :

Passer de MYSQL à PDO


Sujet :

PHP & Base de données

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 6
    Points : 3
    Points
    3
    Par défaut Passer de MYSQL à PDO
    Bonjour,

    Un groupe d'amis et moi sommes en charge de la création d'un service de notifications push via Google Cloud Messaging pour notre projet tuteuré au cours de notre formation en DUT Informatique.

    Etant d'un niveau très moyen en PHP, nous avons rechercher pas mal de tutos sur le net pour nous aider, et sommes tombés sur un tuto vraiment très bien qui avait l'air de bien marcher.
    Cependant, cette version n'est plus prise en charge car ce n'est pas en PDO (ou Mysqli) et rends donc le tout obsolète maintenant que le php 5.5 existe.

    Voici le code que nous avons repris qui est obsolète : http://www.androidhive.info/2012/10/...php-and-mysql/


    J'ai donc procédé à quelques changements pour essayer d'établir une connexion via PDO, mais cela ne marche pas comme nous le voudrions.
    Si j'ai bien compris, les seuls choses qu'il faut changer se trouvent dans le db_connect.php et db_function.php.

    Voici donc les changements que nous avons effectués dans ces deux fichiers (gardez en tête que nous sommes débutant en php, donc il se peut que vous trouviez des choses vraiment absurdes dans notre code que nous n'aurions pas remarqué)

    db_connect.php (modifié)
    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
    <?php
     
    class DB_Connect {
     
     
     
        // constructor
        function __construct() {
     
        }
     
        // destructor
        function __destruct() {
            // $this->close();
        }
     
        // Connecting to database
        // Connecting to database
        public function connect() {
            require_once 'config.php';
     
            try
            {
                $bdd = new PDO('mysql:host='.DB_HOST.';dbname='. DB_DATABASE, DB_USER, DB_PASSWORD);
            }
            catch (Exception $e)
            {
                echo 'Une erreur est survenue !';
                echo 'Erreur : '.$e->getMessage().'<br />';
                echo 'N° : '.$e->getCode();
                die('Erreur : ' . $e->getMessage());
            }
     
            return $db;
     
        }
     
     
        function getDb() {
           if ($this->db instanceof PDO) {
                return $this->db;
           }
        }
     
        // Closing database connection
        function close() {
            mysql_close();
        }
     
    }
    ?>
    db_function.php (modifié)
    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
    <?php
     
    class DB_Functions {
     
        private $db;
     
        //put your code here
        // constructor
        function __construct() {
            include_once './db_connect.php';
            // connecting to database
            $this->db = new DB_Connect();
            $this->db->connect();
     
     
        }
        // destructor
        function __destruct() {
     
        }
     
        /**
         * Storing new user
         * returns user details
         */
        public function storeUser($name, $email, $gcm_regid) {
            // insert user into database
            $result = mysql_query("INSERT INTO gcm_users(name, email, gcm_regid, created_at) VALUES('$name', '$email', '$gcm_regid', NOW())");
            // check for successful store
            if ($result) {
                // get user details
                $id = mysql_insert_id(); // last inserted id
                $result = mysql_query("SELECT * FROM gcm_users WHERE id = $id") or die(mysql_error());
                // return user details
                if (mysql_num_rows($result) > 0) {
                    return mysql_fetch_array($result);
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }
     
        /**
         * Get user by email and password
         */
        public function getUserByEmail($email) {
            $result = mysql_query("SELECT * FROM gcm_users WHERE email = '$email' LIMIT 1");
            return $result;
        }
     
        /**
         * Getting all users
         */
        public function getAllUsers() {
            // $result = mysql_query("select * FROM gcm_users");
           $result = $this->db->getDb()->query("select * FROM gcm_users");
           $result->closeCursor();
     
           return $result;
        }
     
        /**
         * Check user is existed or not
         */
        public function isUserExisted($email) {
            $result = mysql_query("SELECT email from gcm_users WHERE email = '$email'");
            $no_of_rows = mysql_num_rows($result);
            if ($no_of_rows > 0) {
                // user existed
                return true;
            } else {
                // user not existed
                return false;
            }
        }
     
    }
    Merci d'avance pour ceux qui auront prit le temps de tout lire, en espérant que vous pourrez nous aider

  2. #2
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Salut,

    Un tuto pour bien débuter ici.

    Sinon sur le principe vous devriez commencer par faire du code procédural fonctionnel avant de construire des classes. Cela vous permettrait de mieux séparer les problèmes entre l'utilisation de pdo et la construction/utilisation des classes qui est un autre sujet.

    Commencez-donc par faire une connexion à pdo et une requête simple, ainsi vous pourrez avancer progressivement.

  3. #3
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 386
    Points : 5 733
    Points
    5 733
    Billets dans le blog
    1
    Par défaut
    Désolé, je n'ai pas regardé le code, mais j'ai fait quelque chose qui peut vous être utile ; en effet, je suis en train d'actualiser un code qui, notamment, effectue des accès à une bdd MySQL par les fonctions mysql_xxx, et je convertie l'ensemble en PDO.
    Au fur et à mesure, je me suis constitué un petit aide-mémoire qui contient les trucs courants à faire en PDO. Je le donne ici, en laissant le soin aux spécialistes de le corriger ou de compléter :

    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
    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
     
    <?php
    //// connexion (fichier connect_mysql.php)
    require('MyPdo.php');
    try{
       $bdd = new MyPDO();
    }
    catch(PDOException $e){
       echo "argggggggggggggg".$e->getMessage();
    }
     
    // MyPDO (fichier MyPdo.php)
     //la classe MyPdo hérite de la classe PDO (extends)
    class MyPdo extends PDO {
    /* on privilégie les var de classe (statiques) aux constantes : ainsi modifiables par programme */
    	static public $DB_NAME = "xxx";
     
    	static public $HOST = "xxx";
     
    	static public $USER = "xxx";
     
    	static public $PASS = "xxx";
     
     
     
    // le constructeur de MyPdo appelle le constructeur de PDO en lui passant ses paramètres	
    	function __construct() {
    	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
    	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
    	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
     
    	parent::__construct('mysql:host=' . MyPdo::$HOST . ';dbname=' . MyPdo::$DB_NAME, MyPdo::$USER, MyPdo::$PASS, $pdo_options);
    	}
     
    }
    // fin MyPDO
     
     
    //// Effectuer une query et un fetch
    $query = 'SELECT * FROM foo WHERE bar=1;';
    $arr = $bdd->query($query)->fetch(); //Sur une même ligne ...
     
     
    //// Effectuer une query et un fetchAll
    $query = 'SELECT * FROM foo WHERE bar<10;';
    $stmt = $bdd->query($query);
    $arrAll = $stmt->fetchAll(); //... ou sur 2 lignes
     
    //// Effectuer un exec
    $query = 'DELETE FROM foo WHERE bar<10;';
    $rowCount = $bdd->exec($query);
     
    //// nb de lignes (mysql_num_rows)
    $query = 'DELETE FROM foo WHERE bar<10;';
    $rowCount = $bdd->exec($query);
    echo "nb de lignes=".$rowCount;
     
    // nb de lignes pour un select
    $sql='select * from `users` order by nom';
    $qid = $bdd->query($sql);
    //test de mysql_num_rows
    $num_rows=0;
    while( $ligne=$qid->fetch(PDO::FETCH_OBJ) ) $num_rows++;
    $bdd=NULL;
    echo "nb de lignes=".$num_rows;
     
    // exécuter un select puis afficher les lignes
    $sql='select * from `conf` order by lastname';
    $qid = $bdd->query($sql);
    while( $ligne=$qid->fetch(PDO::FETCH_NUM) )...
     
    // exécuter un select puis mettre les données en tableau associatif
    $sql='select * from `conf` order by lastname';
    $qid = $bdd->query($sql);
    $data = $qid->fetchAll(PDO::FETCH_ASSOC); 
    echo $data[0]["name"]; // tableau à 2 dimensions
     
    // faire une requête préparée
    $sql=select * from conf where lastname=:name and firstname=:prenom and nb_conf=:nb;
    $qid=$bdd->prepare($sql);
    $qid->bindparam(:name,"toto",PDO::PARAM_STR);
    $qid->bindparam(:prenom,"prenom_toto",PDO::PARAM_STR);
    $qid->bindparam(:nb,5,PDO::PARAM_INT);
    $qid->execute();
     
    // faire une requête préparée sans bindparam
    $sql=select * from conf where lastname=:name and firstname=:prenom and nb_conf=:nb;
    $qid=$bdd->prepare($sql);
    $qid->execute(array(':name' => "toto", ':prenom' => "prenom_toto",' :nb' => $nb_conf));
     
    ?>
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  4. #4
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    @laurentSc
    Y'a quelques approximations dans tes exemples.

    1/ rowCount() peut être utilisé pour trouver le nombre de lignes affectées par les requêtes de type DELETE, INSERT ou UPDATE, mais à la suite d'un exec() c'est redondant puisque exec() retourne déjà le nombre de lignes affectées...

    Pour certaines bases on peut aussi utiliser rowCount() pour compter le nombre de lignes retournées par une requête de type SELECT. Sinon et pour avoir un code plus générique on peut bien entendu mettre un nombre qui s'incrémente dans la boucle du jeu de résultat comme tu le fais mais si on en a besoin plus tôt dans le code on fait une requête distincte comme dans l'exemple 2 du manuel

    2/ Dans tes premières lignes tu utilise $pdo-> alors que ta connexion se nomme $bdd

    3/ echo $d[0]["name"] devrait être remplacé par echo $data[0]["name"]

    4/ Il manque des exemples d'utilisation des requêtes préparées avec prepare()/execute(). Bien entendu il n'y a pas d'équivalent avec l'extension mysql mais c'est quand même d'un grand intérêt pour les requêtes multiples et la protection des données utilisateur.


    Et bonne année à tous

  5. #5
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 386
    Points : 5 733
    Points
    5 733
    Billets dans le blog
    1
    Par défaut
    Merci pour ton retour ABCIWEB ; j'ai pris en compte tes remarques en corrigeant mon post #3, où j'ai notamment rajouté un exemple de requête préparée.

    Bonne année aussi !

    EDIT : j'ai bien conscience que pour compter les lignes retournées par un select, on pourrait faire une requête COUNT(*), mais j'ai mis la technique que j'emploie.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  6. #6
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    Merci pour ton retour ABCIWEB ; j'ai pris en compte tes remarques en corrigeant mon post #3, où j'ai notamment rajouté un exemple de requête préparée.
    Ce sera plus complet avec un second exemple de requête préparée qui utilise execute() avec un tableau comme paramètre car c'est très pratique (et oui je suis pénible )

    A savoir pour les débutants qui liraient ce sujet, qu'à partir du moment où on a déclaré le mode 'ERRMODE_EXCEPTION', il faudra faire les requêtes dans un bloc try/catch pour gérer les exceptions sinon on aura des retours de type "Uncaught exception..." en cas de problème.
    Au passage il est possible de récupérer différents types d'erreurs depuis le même bloc try :
    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
    <?php
    $profession = filter_input(INPUT_POST,'profession', FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
    if(trim($profession) != false)
    {
    	$query = "SELECT login, email FROM membres WHERE profession = ? AND revenus = 'millionaire'";
     
    	try
    	{
    		if($profession == 'webmestre')
    		{// on peut éviter la requête suivante car on est certain qu'il n'y aura pas de réponse
    			throw new Exception("Profession incompatible");
    		}
    		else if($profession == 'webmaster')
    		{// on peut éviter la requête également
    			throw new Exception("Profession incompatible, pas même en anglais");
    		}
     
    		$bdd = new MyPDO();// classe de connexion
    		$stmt = $bdd->prepare($query);
    		$stmt->execute(array($profession));
     
    		while($result = $stmt->fetch(PDO::FETCH_OBJ))
    		{
    			echo 'Login : '.htmlspecialchars($result->login).' mail : '.htmlspecialchars($result->email).'<br>';
    		}
    	}
    	catch (PDOException $e)// on récupère les erreurs PDO
    	{
    		// Eventuel message en production
    		$erreur = "Erreur dans la requête";
     
    		// message complet uniquement en développement(pas besoin de renseigner plus précisément d'éventuels pirates)
    		$erreur .= ' : '.$e->getMessage();
    	}
    	catch (Exception $e)// on récupère les erreurs générées avec throw
    	{
    		$erreur = $e->getMessage();
    	}
     
    	if(isset($erreur)) echo $erreur;
    }
    ?>

  7. #7
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 386
    Points : 5 733
    Points
    5 733
    Billets dans le blog
    1
    Par défaut
    Pas pénible, mais formateur ; à vrai dire, ça fait pas très longtemps que je connais PDO (et les requêtes préparées, même si ce n'est pas lié) et je ne connaissais que bindparam ; j'ai donc regardé la doc et augmenté mes exemples. Par contre, j'ai quelques remarques par rapport à ton exemple :
    - tu utilises pour les requêtes préparées le marqueur ? ; je trouve plus clair d'utiliser les marqueurs nommés (comme dans mon exemple).
    - tu as mis juste avant l'exécution de la requête la connexion ; or, si dans la page, il y a plusieurs requêtes à exécuter, on ne va pas se connecter à chaque fois (mais juste en début de page et se déconnecter ($bdd=NULL;) à la fin.

    Sinon, le truc d'encapsuler les exécutions de requêtes dans des try/catch, je connaissais pas et en ai testé le bien-fondé. Par contre, j'ai aussi noté une bizarrerie : je l'ai fait dans un code, ai volontairement introduit un bug dans une requête, la deuxième restant correcte, et pourtant, il me signale 2 fois une erreur ; et la même !

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    try {
     
    $query = "bugSELECT * FROM machines where name=?";
     
    $qid = $bdd->prepare($query);
    $qid->execute(array($selected_machine));
     
    while( $row=$qid->fetch(PDO::FETCH_ASSOC) ) {
    	$id = $row["id"];
    	$serveur=$row["name"];
    	}
    }
    catch(PDOException $e) {
    $erreur = $e->getMessage();
    }
    if(isset($erreur)) echo "<br/>".$erreur;	
     
    try{
    $query_info = "SELECT machines.name,infotech.* FROM machines,infotech
    	  WHERE machines.id=? AND machines.name=infotech.name";
    $qid = $bdd->prepare($query_info);
    $qid->execute(array($id));
     
    $row = $qid->fetchAll(PDO::FETCH_ASSOC);
    }
    catch(PDOException $e) {
    $erreur1 = $e->getMessage();
    }
    if(isset($erreur1)) echo "<br/>".$erreur1;

    SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de 'bugSELECT * FROM machines where name='DBMAP'' à la ligne 1
    SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de 'bugSELECT * FROM machines where name='DBMAP'' à la ligne 1
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2015
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2015
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    Je suis un des membres du groupe qui travaille sur ce projet, et j'ai également posté un message sur un autre forum.
    J'ai réussi à me débloqué, mais suis à nouveau confronté à une erreur que je n'arrive pas à résoudre.

    Merci d'avance de votre aide et de nous avoir aider jusque là

  9. #9
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    J'ai donné un tuto dans mon premier message, vous l'avez lu, vous avez fait des tests, des requêtes ? Vous utilisez des fonctions mysql avec une connexion pdo, évidemment ça va pas le faire.

    Il faut faire des tests dans une page séparée, en dehors du contexte de votre code sinon il vous sera très difficile de trouver l'origine des erreurs. C'est aussi le bon moyen pour apprendre. Ensuite vous pourrez intégrer le code.

  10. #10
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    - tu utilises pour les requêtes préparées le marqueur ? ; je trouve plus clair d'utiliser les marqueurs nommés (comme dans mon exemple).
    Tu fais comme tu veux, perso j'utilise les deux. Mais c'est bien de connaître les marqueurs non nommé car cela permet de construire plus facilement des requêtes dynamiques.
    Citation Envoyé par laurentSc Voir le message
    - tu as mis juste avant l'exécution de la requête la connexion ; or, si dans la page, il y a plusieurs requêtes à exécuter, on ne va pas se connecter à chaque fois (mais juste en début de page et se déconnecter ($bdd=NULL;) à la fin.
    J'ai mis la connexion ici pour la cohérence de l'exemple. Sinon on peut aussi faire une classe de connexion statique qui permet de l'appeler plusieurs fois sans soucis tout en utilisant la connexion initiale.

    Sinon la déconnexion en fin de script n'est pas forcément une bonne idée. En cas de scripts imbriqués c'est un vrai casse tête. Et surtout php le fait automatiquement donc je vois pas trop pourquoi tu t'embête avec ça. Si tu veux libérer des ressources suite à un SELECT utilises closeCursor() qui est équivalent de mysql_free_result() et ce sera suffisant.

    Pour la bizarerie faudrait voir en production si tu as le même résultat que sur ton serveur de test.

    Sinon tu devrais protéger tes variables !!! On ne devrait pas voir des exemples comme SELECT * FROM machines where name='".$selected_machine."'"; Soit tu fais une requête préparée (recommandé) soit au minimum il faut utiliser la fonction quote() de php. Là tu donne l'exemple du trou de sécurité n°1 de la sécurité internet : injection sql.

  11. #11
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 386
    Points : 5 733
    Points
    5 733
    Billets dans le blog
    1
    Par défaut
    OK, j'ai remplacé le mot "critiques" par "remarques".
    La déconnexion inutile, même si je n'ai pas encore rencontré son inconvénient, au cas où, je l'ai supprimée de partout.

    Le risque d'injection SQL, tu as raison, mais comme la cible de ce code est de l'intranet et non de l'internet, je doute d'avoir grand-chose à craindre ; cela dit, c'était pas top de donner cet exemple : je l'ai corrigé...

    Pour passer ce code en production, on verra un de ces jours ; j'ai un peu la flemme de créer une bdd MySQL, sachant que le serveur intranet cible héberge lui-même wampserver pour exécuter du PHP et que donc, il risque de reproduire le même défaut (j'ai pas testé) ; il faudrait donc copier tout le code et créer une bdd sur un serveur qui exécute le PHP (sans wampserver !)

    et quelques remarques pour Tokipudi :

    - dans le fichier index.php, la bdd se nomme $db alors que dans aide_memoire.php $bdd ; même si dans index.php, on ne voit pas la connexion, il y a peut-être une erreur...et d'ailleurs, je viens d'en voir une dans aide_memoire.php : vous avez copié-collé mon code avant que je ne le corrige et donc un moment, la bdd est nommée $pdo, qu'il faut remplacer par $bdd...

    - un peu plus loin, vous comptez les lignes d'une requête select avec un rowCount() : ça ne marche pas ; cf l'exemple dans aide_memoire.php...

    - pour comprendre l'erreur signalée par easyphp, il faudrait le fichier où est définie la classe getDb.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  12. #12
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    Le risque d'injection SQL, tu as raison, mais comme la cible de ce code est de l'intranet et non de l'internet, je doute d'avoir grand-chose à craindre ; cela dit, c'était pas top de donner cet exemple : je l'ai corrigé...
    J'ai parlé de trou de sécurité mais il faut également traiter les variables d'une requête pour éviter qu'elles puissent produire une erreur même involontairement (elles pourraient contenir une quote ou une double quote par exemple). Donc cela fait deux bonnes raisons d'utiliser les requêtes préparée (ou sinon d'utiliser la fonction quote()) : sans traitement des variables, la requête ne pourra fonctionner que dans le cas particulier où les variables ne contiennent pas de caractères qui pourraient produire une rupture de la chaine, et en plus elle est exposée aux injections sql.

    Et désolé, mais ton dernier exemple n'est toujours pas bon pour l'instant étant donné que le principe d'une requête préparée est de faire une correspondance entre un ou plusieurs marqueurs et les variables de la requête. Or je ne vois aucun marqueur dans tes requêtes, la requête préparée ne sert donc strictement à rien tel quel et tu as toujours les deux inconvénients que je viens de citer.
    C'est quand même assez simple de se souvenir qu'avec les requêtes préparées on ne devrait jamais voir de variables concaténées dans la requête ! non ? On ne doit voir dans la requête que des marqueurs, nommés ou non, mais pas de variables !. Les variables tu les associe ensuite aux marqueurs avec un bind ou en passant un tableau dans execute().

  13. #13
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 386
    Points : 5 733
    Points
    5 733
    Billets dans le blog
    1
    Par défaut
    OK, je n'avais jamais étudié l'apport des requêtes préparées donc j'avais bien entendu parler du risque des injections SQL, mais je ne savais pas que ça traitait aussi les erreurs dans les variables...
    Et pour ma boulette restée dans mon exemple, elle est corrigée. (les marqueurs ?, ça fait un code plus court).
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  14. #14
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par laurentSc Voir le message
    je ne savais pas que ça traitait aussi les erreurs dans les variables...
    Et pour ma boulette restée dans mon exemple, elle est corrigée. (les marqueurs ?, ça fait un code plus court).
    C'est pas à proprement parler des erreurs, suffirait qu'il y ait une apostrophe dans la valeur de la variable. Et oui les "?" ça fait du code plus court, faut juste faire attention de passer les variables dans le bon ordre dans le tableau quand il y en a plusieurs

    Je vais pas chipoter mais tu aurais dû faire pareil pour l'id dans ta seconde requête sinon il ne sert à rien de faire une requête préparée.
    Dans l'absolu si on a pris soin auparavant de caster l'id en entier, on a pas besoin de le protéger. Mais cela suppose de ne pas oublier de caster préalablement cette variable et donc ta requête est dépendante d'un contexte indispensable. En protégeant toutes les variables sans exception on produit un code générique qu'on peut mieux copier d'un script à l'autre sans se soucier des conditions nécessaires pour que la requête fonctionne correctement et soit bien protégée

  15. #15
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 386
    Points : 5 733
    Points
    5 733
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ABCIWEB Voir le message

    Je vais pas chipoter
    C'est pas chipoter...J'avais pas fait attention...(comme souvent car beaucoup d'erreurs d'inattention )
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

Discussions similaires

  1. Passer de MySQL à PostgreSQL
    Par GLDavid dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 09/05/2007, 12h14
  2. Réponses: 4
    Dernier message: 08/04/2006, 09h10
  3. Passer de Mysql a Sql server
    Par scaleo dans le forum MS SQL Server
    Réponses: 14
    Dernier message: 17/10/2005, 10h47
  4. [Oracle 8i][DBDesigner] Comment passer de MySQL à Oracle ?
    Par tibotibotibo dans le forum Décisions SGBD
    Réponses: 6
    Dernier message: 08/07/2005, 11h41
  5. pk passer de mysql à postgre
    Par pioums dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 03/10/2002, 10h31

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