Publicité
+ Répondre à la discussion Actualité déjà publiée
Page 3 sur 4 PremièrePremière 1234 DernièreDernière
Affichage des résultats 41 à 60 sur 72
  1. #41
    Modérateur

    Inscrit en
    septembre 2010
    Messages
    7 957
    Détails du profil
    Informations forums :
    Inscription : septembre 2010
    Messages : 7 957
    Points : 9 507
    Points
    9 507

    Par défaut

    Citation Envoyé par Madfrix Voir le message
    Jamais utilisé FETCH_CLASS alors je suis pas contre un tuto

    Demain pour 10h c'est possible ?

    J'ai maintenant l'habitude d'utiliser le module Zend_Db pour le mapping et je dois dire que parfois on devient un peu fainéant avec et qu'on oublie "les bases"
    j'en avais fait un petit sur FETCH_GROUP :

    PDO offre une option intéressante dans son fetchMode : PDO::FETCH_GROUP qui permet de grouper des entrées par catégorie.

    exemple :

    Code php
    +----+-----------+----------+-------+
    | id | firstname | lastname | city |
    +----+-----------+----------+-------+
    | 1 | Jean | Machin | Paris |
    | 2 | Jean | Truc | Nice |
    | 3 | Paul | Bla | Nice |
    +----+-----------+----------+-------+

    on a envie de trier les utilisateur par ville pour avoir une sortie type :
    Paris
    Jean Machin
    Nice
    Jean Truc
    Paul Bla
    plusieurs solutions :

    Faire une requête DISTINCT sur les villes, et a chaque tour de boucle allé chercher les personnes qui correspondes
    Créer un array temporaire et a chaque tour de boucle ajouter la personne ($tmp[$user['city']][] = $user) , et reboucler ensuite pour créer son tableau
    A chaque tour de boucle vérifier via un buffer si la ville a été mise et afficher les personnes, sinon afficher ville


    la solution PDO :

    Grâce au fetchAll et son option PDO::FETCH_GROUP, on a en sortie directement un array formateé, avec en clé la catégorie et en valeur les entrées correspondantes
    (par contre attention contraiement a PDO::FETCH_COLUMN, on ne choisie pas qui est la catégorie, ca sera uniquement la première colonne)

    exemple de code :

    Code php
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    try
    {
        $pdo = new PDO('mysql:host=localhost;dbname=test', 'root');
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
    }
    catch (Exception $e)
    {
        exit($e->getMessage());
    }
     
    $query = $pdo->query("SELECT u.city, u.id, u.firstname, u.lastname FROM test_user u");
     
    if($query)
    {
        $result = $query->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_GROUP);
        print_r($result);
    }
    en sortie
    Code :
    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
    Array
    (
        [Paris] => Array
            (
                [0] => Array
                    (
                        [id] => 1
                        [firstname] => Jean
                        [lastname] => Machin
                    )
     
            )
     
        [Nice] => Array
            (
                [0] => Array
                    (
                        [id] => 2
                        [firstname] => Jean
                        [lastname] => Truc
                    )
     
                [1] => Array
                    (
                        [id] => 3
                        [firstname] => Paul
                        [lastname] => Bla
                    )
     
            )
     
    )
    tout simplement

    Si on veux que la catégorie sois un autre champs il suffis de le mettre en premier (le prénom par exemple)

    Code :
    SELECT u.firstname, u.id, u.lastname, u.city FROM test_user u
    Code :
    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
    Array
    (
        [Jean] => Array
            (
                [0] => Array
                    (
                        [id] => 1
                        [lastname] => Machin
                        [city] => Paris
                    )
     
                [1] => Array
                    (
                        [id] => 2
                        [lastname] => Truc
                        [city] => Nice
                    )
     
            )
     
        [Paul] => Array
            (
                [0] => Array
                    (
                        [id] => 3
                        [lastname] => Bla
                        [city] => Nice
                    )
     
            )
     
    )
    et on peux bien sur doubler les valeurs pour avoir des entrées complètes, ce qui sera d'ailleurs plus simple, au niveau portabilité et pour différentes sorties

    Code :
    SELECT u.city, u.id, u.firstname, u.lastname, u.city FROM test_user u
    -- ou version raccourcis
    Code :
    SELECT u.city, u.* FROM test_user u
    Code :
    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
    Array
    (
        [Paris] => Array
            (
                [0] => Array
                    (
                        [id] => 1
                        [firstname] => Jean
                        [lastname] => Machin
                        [city] => Paris
                    )
     
            )
     
        [Nice] => Array
            (
                [0] => Array
                    (
                        [id] => 2
                        [firstname] => Jean
                        [lastname] => Truc
                        [city] => Nice
                    )
     
                [1] => Array
                    (
                        [id] => 3
                        [firstname] => Paul
                        [lastname] => Bla
                        [city] => Nice
                    )
     
            )
     
    )
    il peux y avoir pas mal de combinaison pour les fetch, mais certaine ne marche qu'avec fetch(), d'autre qu'avec fetchAll et d'autre avec setFetchMode, y'en a plein mais beaucoup ne sont pas documentés : http://www.php.net/manual/fr/pdo.constants.php

  2. #42
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : juin 2007
    Messages : 2 326
    Points : 2 381
    Points
    2 381

    Par défaut

    plusieurs solutions :

    * Faire une requête DISTINCT sur les villes, et a chaque tour de boucle allé chercher les personnes qui correspondes
    * Créer un array temporaire et a chaque tour de boucle ajouter la personne ($tmp[$user['city']][] = $user) , et reboucler ensuite pour créer son tableau
    * A chaque tour de boucle vérifier via un buffer si la ville a été mise et afficher les personnes, sinon afficher ville
    Tu avais aussi la solution SQL mais le PDO::FETCH_GROUP n'avait plus d'intérêt ^^

    Code sql :
    1
    2
    3
    4
     
    SELECT city, GROUP_CONCAT( firstname, lastname )
    FROM uneTable
    GROUP BY city

  3. #43
    Modérateur

    Inscrit en
    septembre 2010
    Messages
    7 957
    Détails du profil
    Informations forums :
    Inscription : septembre 2010
    Messages : 7 957
    Points : 9 507
    Points
    9 507

    Par défaut

    tu dois retraiter quand même, et faire un explode pour avoir ton tableau sachant que tu perds le nom de tes colonnes

  4. #44
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : juin 2007
    Messages : 2 326
    Points : 2 381
    Points
    2 381

    Par défaut

    On a rien sans rien ^^

    par contre on fait qu'une seule requête

  5. #45
    Modérateur

    Inscrit en
    septembre 2010
    Messages
    7 957
    Détails du profil
    Informations forums :
    Inscription : septembre 2010
    Messages : 7 957
    Points : 9 507
    Points
    9 507

    Par défaut

    Citation Envoyé par Madfrix Voir le message
    On a rien sans rien ^^

    par contre on fait qu'une seule requête

    tu fais qu'un requêtes pour la solution 2 et 3, faut aussi trouver un séparateur qui ne sois pas dans les resultats aussi

  6. #46
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : juin 2007
    Messages : 2 326
    Points : 2 381
    Points
    2 381

    Par défaut

    je parle pour le cas de figure enoncé, j'ai encore jamais vu de virgule dans le nom ou le prénom

    Mais c'est vrai que PDO::FETCH_GROUP est plus clean, reste à voir le temps de traitement sur grosses volumétries

  7. #47
    Modérateur

    Inscrit en
    septembre 2010
    Messages
    7 957
    Détails du profil
    Informations forums :
    Inscription : septembre 2010
    Messages : 7 957
    Points : 9 507
    Points
    9 507

    Par défaut

    si tu veux un petit exemple simplifié avec FETCH_CLASS

    Code :
    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
    class User
    {
        public $id; 	
        public $firstname;
        public $lastname;
        public $city;
     
        public function getFullname()
        {
            return sprintf('%s, %s', $this->firstname, $this->lastname);
        }
    }
     
    $stmt = $dbh->query("SELECT id, firstname, lastname, city FROM test_user");
    $users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
     
    foreach($users as $user)
    {
        var_dump($user->getFullname());
    }
     
    /*
    string(13) "jean, machine"
    string(10) "jean, truc"
    string(9) "paul, bla"
    */
    on peux biensur le couplé FETCH_GROUP

    on peu le faire direct aussi, mais la ca marche qu'avec setFetchMode
    Code :
    1
    2
    3
    4
    5
    6
    7
    $stmt = $dbh->query("SELECT id, firstname, lastname, city FROM test_user");
    $stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
     
    while($user = $stmt->fetch())
    {
        var_dump($user->getFullname());
    }

  8. #48
    Membre Expert Avatar de Madfrix
    Profil pro
    Inscrit en
    juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : juin 2007
    Messages : 2 326
    Points : 2 381
    Points
    2 381

    Par défaut

    Merci l'ami, c'est simple et facilement compréhensible

  9. #49
    Modérateur

    Inscrit en
    septembre 2010
    Messages
    7 957
    Détails du profil
    Informations forums :
    Inscription : septembre 2010
    Messages : 7 957
    Points : 9 507
    Points
    9 507

    Par défaut

    un autre exemple avec FETCH_CLASSTYPE, qui lui va prendre le nom de la premier colonne pour créer l'objet a la classe du même nom. (en rajoutant la colonne rôle, qui est sois admin sois guest
    Code :
    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
     
    class Guest
    {
        public $id; 	
        public $firstname;
        public $lastname;
        public $city;
     
        public function getFullname()
        {
            return sprintf('%s, %s', $this->firstname, $this->lastname);
        }
    }
     
    class Admin extends Guest
    {
        public function getUsers()
        {
            //blabla
        }
    }
     
    $stmt = $dbh->query("SELECT role, id, firstname, lastname, city FROM test_user");
    $stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
     
    while($user = $stmt->fetch())
    {
        var_dump(get_class($user));
    }
    /*
    string(5) "Admin"
    string(5) "Guest"
    string(5) "Guest"
    */
    c'est pas très percutant comme exemple mais ca montre mais ca pourrais servir dans le cas d'un UNION par exemple avec des tables différentes

  10. #50
    Membre expérimenté
    Avatar de FMaz
    Inscrit en
    mars 2005
    Messages
    649
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 649
    Points : 527
    Points
    527

    Par défaut

    RunCodePHP m'a fait remarqué une importante erreur dans l'article. En effet, à plusieurs endroits (les joies du copier coller) j'avais ceci:
    Code :
    1
    2
    3
    4
     
    $pdo->prepare($query);
    $pdo->bindValue(1, 6, PDO::PARAM_INT);
    $prep = $pdo->execute();
    Prepare() retourne un PDOStatement, ce qui n'est pas le cas de la méthode execute().
    J'ai donc corrigé les exemples en question afin qu'il soient tel que:
    Code :
    1
    2
    3
    4
     
    $prep = $pdo->prepare($query);
    $prep->bindValue(1, 6, PDO::PARAM_INT);
    $prep->execute();

    Voilà, désolé pour cette erreur, et encore merci à RunCodePHP

  11. #51
    Expert Confirmé
    Avatar de christele_r
    Femme Profil pro Christele Rubneau
    Responsable de service informatique
    Inscrit en
    novembre 2009
    Messages
    1 319
    Détails du profil
    Informations personnelles :
    Nom : Femme Christele Rubneau
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : novembre 2009
    Messages : 1 319
    Points : 2 741
    Points
    2 741

    Par défaut

    Citation Envoyé par FMaz Voir le message
    Hum-hum...
    Je n'avais pas vu la chose sous cet angle...
    Mais c'est vrai qu'il y a un manque à combler à ce niveau.
    Pour ma part, je constates que le TRY est utilisé avec
    $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    chez les rares qui demandent le renvoie des exeptions. lors de la connection.

    Alors encore plus rare sont ceux qui craient un TRY pour les requétes
    Bien sur l'attribut est acquis a $bdd quand au retour d'exeptions,
    mais encore faut'il un CATCH qui les reçoivent.

    Et la c'est le floux absolu, deux écoles :
    mettre les requétes dans le TRY de connection, donc un seul CATCH
    Ou un TRY par requéte

  12. #52
    Membre expérimenté
    Avatar de FMaz
    Inscrit en
    mars 2005
    Messages
    649
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 649
    Points : 527
    Points
    527

    Par défaut

    Maurisier:

    Normalement les gens se font des gestionnaire de connection et d'erreur afin de centraliser la gestion des erreurs.

    Par exemple, sur les gros projets, les erreurs de requêtes seront forcément traitées (loggué quelque part). Ainsi, on se doute bien que les développeurs ne copie-collent pas le code d'ouverture et d'écriture dans un fichier à chaque fois qu'ils ont une requête.

    L'avantage de l'orienté objet est que les classes PDO peuvent être étendues.
    De plus, si une exception n'est pas capturée, elle est transmise à la fonction parent. Une erreur fatale d'uncatched exception arrivera uniquement si au terme de la récursion il n'y a pas eu de capture.

    En somme, pour tracer une image grossière, si tu as un index.php comme front-controlleur unique, il te suffirait de créer un gros try-catch et l'ensemble de ce qui est chargé par ce fichier (c'est à dire tout ton code) sera capturé.

  13. #53
    Expert Confirmé
    Avatar de christele_r
    Femme Profil pro Christele Rubneau
    Responsable de service informatique
    Inscrit en
    novembre 2009
    Messages
    1 319
    Détails du profil
    Informations personnelles :
    Nom : Femme Christele Rubneau
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : novembre 2009
    Messages : 1 319
    Points : 2 741
    Points
    2 741

    Par défaut

    FMaz:
    Oui j'entends bien, mais il reste désagréable d'incruster dans un seul TRY
    tout un code ... et perdu a la fin du php le Catch ...
    Ton exemple a ce sujet est trop sommaire.
    Tu vas te retrouver avec des includes etc ... pffff en plus c'est pas beau a lire.

  14. #54
    Membre expérimenté
    Avatar de FMaz
    Inscrit en
    mars 2005
    Messages
    649
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 649
    Points : 527
    Points
    527

    Par défaut

    Heu ?? Je suis pas certain de comprendre ce que tu essaie d'exprimer. D'ailleurs de quel "exemple" parle-tu exactement ?
    En ce qui me concerne, c'est un article sur PDO, pas sur la gestion des exceptions, et encore moins sur la façon de gérer ses inclusions de fichiers.

    De plus si tu regarde les exemples du manuel PHP, tu verra qu'ils placent la connexion dans un try catch aussi, car la connexion n'utilise que les exceptions.

    Après si tu ne veux pas utiliser les exceptions, tu n'es pas obligé. Mais on est en 2010 avec PHP 5 (pour ne pas dire 5.3), alors je ne vais pas recommander de gérer ses erreurs en PHP 4... mais je n'ai rien contre ca, et l'article indique bien comment ne pas utiliser les exceptions.

  15. #55
    Expert Confirmé
    Avatar de christele_r
    Femme Profil pro Christele Rubneau
    Responsable de service informatique
    Inscrit en
    novembre 2009
    Messages
    1 319
    Détails du profil
    Informations personnelles :
    Nom : Femme Christele Rubneau
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : novembre 2009
    Messages : 1 319
    Points : 2 741
    Points
    2 741

    Par défaut

    FMaz:
    Bien sur bien sur je comprends tout cela
    Je parlais de récupérer les exeption sur les requétes PDO elles mêmes,
    bien sur pas sur du PHP
    Mais c'est bon n'en parlons plus.

  16. #56
    Membre expérimenté
    Avatar de FMaz
    Inscrit en
    mars 2005
    Messages
    649
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 649
    Points : 527
    Points
    527

    Par défaut

    Oui, je parlais de ca aussi.

    Tu dois mettre en place un mécanisme de gestion des exceptions. Si c'est bien fait, c'est transparent. Dans mon cas j'ai un connexion manager qui instancie une classe étendue de PDO, qui elle est en lien avec un error manager.

    De cette facon, j'instancie ma connexion, puis la gestion des erreurs et des statistiques est prises en charge en arrière plan sans que ca soit visible.

    Mais c'est hors du spectre de l'article, j'en ai donc pas parlé... pour le moment.

  17. #57
    Membre régulier
    Inscrit en
    avril 2003
    Messages
    361
    Détails du profil
    Informations forums :
    Inscription : avril 2003
    Messages : 361
    Points : 84
    Points
    84

    Par défaut

    Citation Envoyé par FMaz Voir le message
    De plus, j'aimerais faire une mise en garde que l'utilisation des requêtes préparée n'est pas une protection absolue contre les injections. Vous devez tout de même valider vos entrés. (Donc si tu les a bien validée comme tu le dis, il ne devrait pas y avoir de problème).
    Que faut-il faire alors pour s'assurer que la requête est protégée ?

  18. #58
    Modérateur

    Inscrit en
    septembre 2010
    Messages
    7 957
    Détails du profil
    Informations forums :
    Inscription : septembre 2010
    Messages : 7 957
    Points : 9 507
    Points
    9 507

    Par défaut

    Envoyé par FMaz
    De plus, j'aimerais faire une mise en garde que l'utilisation des requêtes préparée n'est pas une protection absolue contre les injections. Vous devez tout de même valider vos entrés. (Donc si tu les a bien validée comme tu le dis, il ne devrait pas y avoir de problème).
    moi j'aimerai bien un exemple.

  19. #59
    Membre chevronné
    Profil pro
    Inscrit en
    juin 2004
    Messages
    782
    Détails du profil
    Informations personnelles :
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : juin 2004
    Messages : 782
    Points : 791
    Points
    791

    Par défaut

    Je pense que ce qu'il veut dire, c'est que requête préparée n'est pas synonyme de protection contre les injections. Encore faut-il savoir les utiliser.

    Je te renvoie vers un de tes posts ou tu expliques à quelqu'un comment les utiliser : http://www.developpez.net/forums/d10...e/#post5747039

    a mon avis la remarque de FMaz vise à ne pas mettre de fausses certitudes dans l'esprit des débutants notamment.
    • Mon blog PHP : http://blog.alterphp.com
    • "Peace cannot be kept by force, it can only be achieved by Understanding" -- Albert Einstein

  20. #60
    Membre expérimenté
    Avatar de FMaz
    Inscrit en
    mars 2005
    Messages
    649
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 649
    Points : 527
    Points
    527

    Par défaut

    Exactement.

    L'article à été écris pour être une base d'apprentissage saine à PDO. J'ai donc essayé de casser certains "mythes". Par la suite, la lecture d'article plus poussée devrait être facilité.

    Quoi qu'il en soit, de ce que je sais, et sous toute réserve, l'utilisation d'une requête préparée et le passage des variables par les fonctions BIND est une protection suffisante concernant --seulement-- l'injection SQL.

    Par contre, ca ne garanti pas la sécurité de la donnée pour les autres failles. Par exemple si le champs du nom d'utilisateur permet de stocker du code javascript, il est possible que ca permette d'exploiter d'autres failles qui ne sont pas spécifiquement liées à la base de données.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •