Bonjour,

Je fait actuellement un questionnaire en ligne, avec une inscription avant de répondre aux questions.

Pour cela j'ai créer 3 tables dans mysql, une table user, une table liste_questions et une table reponses_user

J'aimerai que le auto_increment de l'user, se retrouve dans la table reponse_user lorsque le participant à répondu à la question.

Le problème c'est que si il y a deux user qui on le même nom et bien l'auto-increment ajouté est celui du premier user (et j'aimerai bien que ce soit celui du deuxieme)

voici mon code :

connexioncontroller.php

public function executeIndex(\Library\HTTPRequest $request)
  {

    unset($_SESSION['auth']);
    unset($_SESSION['player_name']);

      $player = new \Library\Entities\Player(array(

        'player_name' => $request->postData('player_name'),
        'player_mail' => $request->postData('player_mail')

      ))
      ;

     $formBuilder = new \Library\FormBuilder\PlayersFormBuilder($player);
     $formBuilder->build();

     $form = $formBuilder->form();

    if($request->method() == 'POST' && $form->isValid())

    {

      $this->managers->getManagerOf('Players')->save($player);
      $this->app->user()->setFlash('Votre compte a bien été crée ;-)');
    }

    $this->page->addVar('form', $form->createView());
    $this->page->addVar('title', '1ere question');
    $this->page->addVar('title', 'Connexion');

    if ($request->postExists('player_name'))
    {
      $player_name = $request->postData('player_name');
      $player_mail = $request->postData('player_mail');

      if (!empty($player_name) && !empty($player_mail))
      {

        $_SESSION['player_name'] = $player_name;
        $this->app->user()->setAuthenticated(true);
        $this->app->httpResponse()->redirect('/questions-1.html');

      }
      else
      {
        $this->app->user()->setFlash('Le pseudo ou le mot de passe est incorrect.');

      }
    }
  }
}

QuestionController.php

public function executeShow(\Library\HTTPRequest $request)

  {

      $infos_questions = $this->managers->getManagerOf('Questions')->getQuestion($request->getData('id'));

      $infos_player = $this->managers->getManagerOf('Players')->getPlayers($_SESSION['player_name']);

      $reponse = new \Library\Entities\Reponse(array(

        'numero_question' => $request->getData('id'),
        'id_player' => $infos_player['id_player'],
        'question' => $infos_questions['question'],
        'choix1' => $infos_questions['choix1'],
        'choix2' => $infos_questions['choix2'],
        'choix3' => $infos_questions['choix3'],
        'reponse' => $request->postData('reponse')
      ))
      ;

     $formBuilder = new \Library\FormBuilder\QuestionsFormBuilder($reponse);
     $formBuilder->build();

     $form = $formBuilder->form();

    if($request->method() == 'POST' && $form->isValid())

    {

            $reponse_question = $infos_questions['reponse'];

                      if ($reponse_question == $request->postData('reponse'))

                          {

                              $this->managers->getManagerOf('Reponses')->save($reponse);
                              $this->app->user()->setFlash('Votre réponse a bien été ajoutée ;-)');
                              $this->app->httpResponse()->redirect('questions-'.$request->getData_next('id').'.html');

                          }

                      else

                          {

                              $this->managers->getManagerOf('Reponses')->save($reponse);
                              $this->app->user()->setFlash('Votre réponse est fausse et votre session a expiré');
                              $this->app->httpResponse()->redirect('/');

                          }

    }  

    $this->page->addVar('infos_questions', $infos_questions);
    $this->page->addVar('form', $form->createView());
    $this->page->addVar('title', '1ere question');

  }

PlayersManager_PDO.php

protected function add(Player $player)
  {
     
    $q = $this->dao->prepare('INSERT INTO user SET  player_mail = :player_mail, player_name = :player_name,  date = NOW()');
     
    $q->bindValue(':player_name', $player->player_name());
    $q->bindValue(':player_mail', $player->player_mail());
     
    $q->execute();
     
     
    $player->setId($this->dao->lastInsertId());
  }
   
  public function getPlayers($id)
       
      {
         
        $q = $this->dao->prepare('SELECT * FROM user WHERE player_name = :id_player');
        $q->bindValue(':id_player', $id);
        $q->execute();
     
        $q->setFetchMode(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, '\Library\Entities\Player');
     
        return $q->fetch();
         
      }

ReponseManager_PDO.php

protected function add(Reponse $reponse)
  {

    $q = $this->dao->prepare('INSERT INTO reponses_utilisateurs SET  id_session = :id_player, reponse = :reponse, question = :question, numero_question = :numero_question,  date = NOW()');

    $q->bindValue(':id_player', $reponse->id_player());
    $q->bindValue(':numero_question', $reponse->numero_question());
    $q->bindValue(':question', $reponse->question());
    $q->bindValue(':reponse', $reponse->reponse());

    $q->execute();

    $reponse->setId($this->dao->lastInsertId());

  }

Merci de m'éclairer

11 réponses


Alexandre #lbac
Réponse acceptée

Pourquoi tu inscrit les gens avec nom prénoms s'il y a la possibilitée d'en avoir plusieurs ? Tu enregistres/connectes avec l'adresse email que tu définis en tant qu'unique, ça serait plus simple non ?

Le couple Nom+prenom n'étant pas fiable, utilise un Pseudo ou un email par utilisateur, tu as juste à vérifier que le Pseudo ou l'email n'est pas déjà pris.
Ensuite travaille avec l'ID du User pour lier tes tables.

jeanmaki
Auteur

Merci huggy, pour ta réponse, il n'est pas possible de récupérer l'id du user tout de suite après l'inscription ? J'ai essayé en modifiant le getplayer de cette manière

PlayersManager_PDO.php

public function getPlayers($id)

      {

        $q = $this->dao->prepare('SELECT * FROM user WHERE id_player = :id_player');
        $q->bindValue(':id_player', $id);
        $q->execute();

        $q->setFetchMode(\PDO::FETCH_CLASS | \PDO::FETCH_PROPS_LATE, '\Library\Entities\Player');

        return $q->fetch();

      }

et j'ai cette erreur qui s'affiche :

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id_session' cannot be null' in C:\wamp\www\rapid\Library\Models\ReponsesManager_PDO.class.php on line 18
( ! ) PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id_session' cannot be null in C:\wamp\www\rapid\Library\Models\ReponsesManager_PDO.class.php on line 18

Pour récupérer une id juste après son insertion tu as $pdo->lastInsertId();

jeanmaki
Auteur

Le problème c'est que lastInsertid(), prends le dernier id inscrit, et si j'ai deux fois le même prénom et bien l'id du premier inscrit prendra l'id du dernier inscrit du même nom

Bonjour, :)

à vue de nez, je ne vois qu'une solution (j'ai pas chercher plus loin), tu créer un token unique à l'inscription, à la connexion, tu récupère ce token et quand tu as besoin de l'id d'un membre tu la cherche grâce au token.

Cordialement.

Pourquoi tu inscrit les gens avec nom prénoms s'il y a la possibilitée d'en avoir plusieurs ? Tu enregistres/connectes avec l'adresse email que tu définis en tant qu'unique, ça serait plus simple non ?

Exact, c'est pas une mauvaise idée. :)

Puis surtout ça éviterait les soucis de connexion. Sur Facebook par exemple tu auras peut être plusieurs personnes avec le même nom prénom que moi, mais mon adresse email est, elle, unique ;)

jeanmaki
Auteur

Merci, pour vos réponses l'adresse mail est une bonne idée car effectivement elle est unique ;-)
J'ai trouvé aussi la fonction session_id() que j'utilise avec session_regenerate_id(); ce qui donne une id de session différente a chaque ouverture de session.
Est ce que cette chaine de caractère peut avoir la même valeur lorsque deux sessions s'ouvre en même temps? ou la valeur de session utilisé est unique?

Le risque zéro n'existe pas, il ce peux qu'il y ai ce qu'on apelle des colisions, c'est à dire qu'à un moment T, deux id soit identique. Bien que cela soit rare ce n'est pas impossible.

jeanmaki
Auteur

merci ! ;-)