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 :

Objet non retourné depuis une requête sql


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web Full-Stack
    Inscrit en
    Mai 2019
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Maroc

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 19
    Points : 31
    Points
    31
    Par défaut Objet non retourné depuis une requête sql
    Bonsoir,

    Je dispose de base de la class Personnage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class Personnage
    {
        private $_id,
                $_name,
                $_damage;
     
        const ITS_ME = 1;
        const PERSO_DEAD = 2;
        const PERSO_HIT = 3;
     
        public function name() { return $this->_name; }
    }
    Mon routeur dispose d'un formulaire où l'on peut entrer un nom, et ceci va récupérer les informations sur le personnage depuis une méthode getPerso() dans la classe PersonnagesManager :
    On peut le présenter comme suit :

    Si l'utilisateur veut utiliser un personnage déjà existant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // If want use a character
    elseif(isset($_POST['use']) && isset($_POST['name']))
    {
        if($manager->exist($_POST['name']))
        {
            $perso = $manager->getPerso($_POST['name']);
        }
        else
        {
            $message = 'Ce personnage n\'existe pas !';
        }
    }
    Si $perso est définie, alors on peut afficher la page d'informations :
    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
     
    if(isset($perso))
            {
                print_r($perso);
            ?>
     
            <p><a href="?deconnexion=1">Déconnexion</a></p>
     
            <fieldset>
                <legend>Mes informations :</legend>
                <p>
                    Nom : <strong><?php echo htmlspecialchars($perso->name()); ?></strong><br/>
                    Dégats : <strong><?php echo $perso->damage(); ?></strong>
                </p>
            </fieldset>
     
            <fieldset>
                <legend>Qui frapper ?</legend>
                <p>
                <?php  
                $persos = $manager->getListPerso($perso->name());
     
                if(empty($persos))
                {
                    echo 'Personne à frapper !';
                }
                else
                {
                    foreach($persos as $onePerso)
                    {
                        echo "<a href='?hit=" . $onePerso->id() . "'>" . htmlspecialchars($onePerso->name()) . "</a> Dégats : (" . $onePerso->damage() . ")<br/>";
                    }
                }          
                ?>
            </fieldset>
     
            <?php
            }
            else
            {     
            ?>
     
            <form action="" method="post">
                <p>
                    Nom : <input type="text" name="name" maxlength="50" />
                    <input type="submit" value="Create Character" name="create" />
                    <input type="submit" value="Use Character" name="use" />
                </p>
            </form>
     
            <?php
            }
            ?>
    Dans ma class PersonnagesManager je dispose de la méthode vu précédement qui est getPerso() et qui se présente comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public function getPerso($info)
        {
            $column = is_int($info) ? 'id' : 'namePerso';
            $q = $this->_db->prepare('SELECT id, namePerso, damage FROM personnages WHERE ' . $column . '=:' . $column);
            $q -> bindValue(':' . $column, $info);
     
            $q -> execute();
     
            return new Personnage($q->fetch(PDO::FETCH_ASSOC));
        }
    ---------------------------

    Le problème est : Que lorsque je crée mon personnage, tout se passe bien et $perso->name() (son nom) est bien affiché, mais quand je me déconnectes et souhaites utiliser ce dernier, je n'arrive pas à récupérer son nom ! Et les autres infos sont bien récupérés pourtant !

    J'ai pratiquer quelques tests :

    - En affichant le nom directement dans la classe ce qui me donne :
    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
     
    public function getPerso($info)
        {
            $column = is_int($info) ? 'id' : 'namePerso';
            $q = $this->_db->prepare('SELECT id, namePerso, damage FROM personnages WHERE ' . $column . '=:' . $column);
            $q -> bindValue(':' . $column, $info);
     
            $q -> execute();
     
            $donnees = $q -> fetch(PDO::FETCH_ASSOC);
            echo $donnees['namePerso'];
            exit();
     
            //return new Personnage($q->fetch(PDO::FETCH_ASSOC));
        }
    Résultat : Mon nom est bien affiché !
    Nom : Capture.JPG
Affichages : 88
Taille : 28,2 Ko


    - En envoyant uniquement le nom comme suit :
    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
     
    public function getPerso($info)
        {
            $column = is_int($info) ? 'id' : 'namePerso';
            $q = $this->_db->prepare('SELECT id, namePerso, damage FROM personnages WHERE ' . $column . '=:' . $column);
            $q -> bindValue(':' . $column, $info);
     
            $q -> execute();
     
            $donnees = $q -> fetch(PDO::FETCH_ASSOC);
     
            return new Personnage(['name' => $donnees['namePerso']]);
     
            //return new Personnage($q->fetch(PDO::FETCH_ASSOC));
        }
    Résultat : Il me retourne bien le nom et l'affiche mais du coup les autres informations ne sont plus disponibles ? Comment est-ce possible ?
    Nom : Capture.JPG
Affichages : 96
Taille : 56,7 Ko

    Merci beaucoup de votre aide !

  2. #2
    Membre émérite Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 896
    Points : 2 835
    Points
    2 835
    Par défaut
    Bonjour,

    Le code de ta classe personnage est complet dans ce que tu nous donnes ?
    Parce que ta classe ne fait rien du tout là ^^

    Au minimum, il te faudrait un constructeur comme ça :
    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
    class Personnage
    {
     
        private $_id,
                $_name,
                $_damage;
     
        public function __construct($pdoResult = [])
        {
            // On déclare les valeurs par défaut des propriétés de notre objet Personnage
            if (!empty($pdoResult['id'])) {
                $this->_id = $pdoResult['id'];
            }
            if (!empty($pdoResult['namePerso'])) {
                $this->_name = $pdoResult['namePerso'];
            }
            if (!empty($pdoResult['damage'])) {
                $this->_damage = $pdoResult['damage'];
            }
        }
     
        public function name()
        {
            return $this->_name;
        }
     
    }
     
    // Test rapide :
    $perso = new Personnage([
        'id' => 1,
        'namePerso' => 'Son Goku',
        'damage' => 'Over 9000',
            ]);
    echo PHP_EOL . '<pre>' . print_r($perso, true) . '</pre>' . PHP_EOL;
    echo PHP_EOL . '<pre>name: ' . print_r($perso->name(), true) . '</pre>' . PHP_EOL;

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web Full-Stack
    Inscrit en
    Mai 2019
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Maroc

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 19
    Points : 31
    Points
    31
    Par défaut
    Non elle n'est pas complète, mais le problème ne doit pas venir de là, car elle s'occupe uniquement de renvoyer le nom qui a déjà été récupéré. Le problème c'est que en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return new Personnage(['name' => $donnees['namePerso']]);
    Il va en effet me renvoyé le Nom correct ! Mais pas les autres infos du coup !

    Mais si je fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return new Personnage($q->fetch(PDO::FETCH_ASSOC));
    Ici je m'attends à ce qu'il me renvoi l'id, le nom et les dégats (damage) mais il ne renvoi pas le nom !

    Sinon pour la class Personnage la voici en complet :
    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
     
    <?php
     
    class Personnage
    {
        private $_id,
                $_name,
                $_damage;
     
        const ITS_ME = 1;
        const PERSO_DEAD = 2;
        const PERSO_HIT = 3;
     
        public function __construct(array $donnees)
        {
            $this->hydrate($donnees);
        }
     
        public function hydrate(array $donnees)
        {
            foreach($donnees as $key => $value)
            {
                $method = 'set' . ucfirst($key);
     
                if(method_exists($this, $method))
                {
                    $this->$method($value);
                }
            }
        }
     
        public function hit(Personnage $perso)
        {
            if($perso->id() == $this->_id)
            {
                return self::ITS_ME;
            }
     
            return $perso->haveDamage();
        }
     
        public function haveDamage()
        {
            $this->_damage += 5;
     
            if($this->_damage >= 100)
            {
                return self::PERSO_DEAD;
            }
     
            return self::PERSO_HIT;
        }
     
     
        public function id() { return $this->_id; }
     
        public function name() { return $this->_name; }
     
        public function damage() { return $this->_damage; }
     
     
        public function setId($id)
        {
            $id = (int) $id;
     
            if($id > 0)
            {
                $this->_id = $id;
            }
        }
     
        public function setName($name)
        {
            if(is_string($name))
            {
                $this->_name = $name;
            }
        }
     
        public function setDamage($damage)
        {
            $damage = (int) $damage;
     
            if($damage >= 0 && $damage <= 100)
            {
                $this->_damage = $damage;
            }
        }
     
        public function validateName()
        {
            return !empty($this->_name);
        }
    }

  4. #4
    Membre émérite Avatar de darkstar123456
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 896
    Points : 2 835
    Points
    2 835
    Par défaut
    Oui et justement c'est normal, d'où le fait que je parle de la classe incomplète.
    As-tu affiché/testé ta classe "proprement" et comparé à un résultat de ta requête PDO ?
    Je ne pense pas, car tu aurais vu qu'entre ce que TU testes et ce que PDO t'envoie, il y a une fameuse différence.

    Je prends par exemple le nom du perso (cela figurait d'ailleurs dans mon code mais je ne l'avais pas souligné car c'est LA BASE) :
    Tu testes de la façon suivante :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    return new Personnage(['name' => $donnees['namePerso']]);
    Là ça fonctionne, car si on analyse ton code, ça passe par $this->hydrate() qui appelle $this->setName() car la clé de ton array est name.

    Or dans PDO, où est-ce que tu renseigne quelque part que la clé est name ? Nul part.
    Donc il essaye d'atteindre la classe $this->setNamePerso() (car namePerso est la clé de ton array retourné par PDO) mais cette méthode n'existe pas.

    Deux choix ici :
    1] changer le nom de la méthode et l'assignation de la variable
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public function setNamePerso($name)
    {
        if(is_string($name))
        {
            $this->_name = $name;
        }
    }

    OU

    2] réécrire la requête SQL : $q = $this->_db->prepare('SELECT id, namePerso AS name /* on change la clé retournée pour correspondre à ta classe */, damage FROM personnages WHERE ' . $column . '=:' . $column);

    PS : Si tu as d'autres questions, merci de ne pas couper dans ton code, c'est plus rapide et simple pour tout le monde ;-)

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web Full-Stack
    Inscrit en
    Mai 2019
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : Maroc

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

    Informations forums :
    Inscription : Mai 2019
    Messages : 19
    Points : 31
    Points
    31
    Par défaut
    Ah mais oui ! T'a totalement raison, sérieux ça faisait 4 jours que je bloquait dessus sans trouver de solutions ! Merci à toi !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. champs vides non retournés par une requête
    Par roro06 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 13/03/2008, 18h42
  2. Remplissage de QComboBox depuis une requête SQL
    Par L0101SA dans le forum Bases de données
    Réponses: 2
    Dernier message: 01/03/2008, 20h42
  3. Lancement d'un exe depuis une requête SQL
    Par mister_rom dans le forum Développement
    Réponses: 5
    Dernier message: 29/11/2007, 10h27
  4. Valeur non trouvé dans une requète SQL
    Par Jeankiki dans le forum Bases de données
    Réponses: 2
    Dernier message: 15/12/2006, 16h36
  5. variable non reconnue dans une requête sql
    Par sanatou dans le forum C++
    Réponses: 3
    Dernier message: 13/12/2006, 17h43

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