Problème syntaxe SQL en PDO

Bonjour à tous

Voici mon problème

<?php	
try {
	
$connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");

$retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
$donnees = $connexion->query($retour);
if ($donnees['nbre_entrees'] == 0){
$connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES (:".$_SERVER['REMOTE_ADDR'].",:.time())");}
else{			
$connexion->exec("UPDATE connectes SET timestamp=' . time() . ' WHERE ip=".$_SERVER['REMOTE_ADDR']);}

$timestamp_5min = time() - (60 * 5);
$connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);

$retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
$donnees = $connexion->query($retour);
$columns = $donnees->fetch();
$nb = $columns['nbre_entrees'];
echo "".$nb."";

} catch(PDOException $e) {
    echo 'Erreur PDO : '.$e->getMessage();
}
?>


Résultat: Page blanche :( à cause de la ligne

$columns = $donnees->fetch();


Ce code fonctionne en mysql mais je bloque sur le PDO.

Pouvez-vous m'aider s'il vous plaît ?

Voici le code d'origine qui fonctionne:

<?php
ob_start();

$mysql_server='12345';
$mysql_name='12345';
$mysql_user='12345';
$mysql_pass='12345';

session_start();
mysql_connect($mysql_server,$mysql_user,$mysql_pass) or die('Erreur de connexion à la base de données MySQL');
mysql_select_db($mysql_name) or die('Erreur d\'accès à la base de données MySQL');
mysql_query('SET CHARACTER SET "utf8";');
mysql_query('SET collation_connection = "utf8_general_ci";');
mysql_query('SET NAMES "utf8";');


$retour = mysql_query('SELECT COUNT(*) AS nbre_entrees FROM connectes WHERE ip=\'' . $_SERVER['REMOTE_ADDR'] . '\'');
$donnees = mysql_fetch_array($retour);

if ($donnees['nbre_entrees'] == 0)
{
    mysql_query('INSERT INTO connectes VALUES(\'' . $_SERVER['REMOTE_ADDR'] . '\', ' . time() . ')');
}
else
{
    mysql_query('UPDATE connectes SET timestamp=' . time() . ' WHERE ip=\'' . $_SERVER['REMOTE_ADDR'] . '\'');
}

$timestamp_5min = time() - (60 * 5);
mysql_query('DELETE FROM connectes WHERE timestamp < ' . $timestamp_5min);


$retour = mysql_query('SELECT COUNT(*) AS nbre_entrees FROM connectes');
$donnees = mysql_fetch_array($retour);

echo "".$donnees['nbre_entrees']."";
?>

20 réponses

Résumé de la discussion

Le fil porte sur une migration de mysql_ vers PDO en PHP pour compter les entrées d'une table connectes et manipuler des horodatages via time() et NOW(). Les échanges identifient des erreurs PDO fréquentes: usage de COUNT(*), fetch sur le bon objet, et quotes autour de time() qui génèrent des syntaxes SQL et SQLSTATE 42000. Plusieurs propositions préconisent d’effectuer les requêtes séparément, d’utiliser fetch() sur le résultat, d’éviter les quotes autour de time(), et d’activer error_reporting pour déceler les messages. En parallèle, certains soulignent qu’une syntaxe invalide comme COUNT (*) ou l’absence d’échappement des adresses IP peut bloquer l’exécution, et recommandent d’isoler les requêtes et d’utiliser des requêtes préparées.

Bobot (l’IA à votre service)
  1. Je viens de mettre NOW()

    C'est comme pour time()

    Ca fait 0 visiteur(s) !
    1. Modérateur
      je te répète une dernière fois ma question ...

      AS TU TESTE TA REQUETE DIRECTEMENT DANS TA BDD ????

  2. Oui mais ca fonctionne pas
    1. Modérateur
      ton champ est en Timestamp ?
      Pourquoi ne pas l'avoir mis en DateTime ??
    2. Aucune idée c'était comme ça
    3. Modérateur
      Et puis.. NOW() devrait fonctionner ...
      As tu testé ta requête EN DIRECT DANS TA BDD ?????
  3. J'ai besoin au format TIMESTAMP

    Les 3 formats proposés ne correspondent pas.
    1. Modérateur
      et tu as essayé NOW() ?
  4. J'ai remplacé time() par CURRENT_TIMESTAMP mais ça fonctionne pas...

    $sql = "INSERT INTO connectes 
                (ip,timestamp) 
                VALUES ('".$_SERVER['REMOTE_ADDR']."',
                CURRENT_TIMESTAMP)";
    
    1. Modérateur
      http://www.w3schools.com/sql/func_curdate.asp
  5. ok ok si j'enlève les quote autour de time() c'est page blanche ! Merde je pensais avoir trouvé :(

    Bon je vais essayer de sortir les requêtes une par une.

    je fais la première:

    <?php
    error_reporting(E_ALL);
    try 
    {
    $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
    $connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch(PDOException $e) 
    {
    echo 'Erreur PDO : '.$e->getMessage();
    }
    ?>
    <?php
    $sql = "INSERT INTO connectes 
                (ip,timestamp) 
                VALUES ('".$_SERVER['REMOTE_ADDR']."',time())";
    
    try {
       $connexion->exec($sql);
    } catch(PDOException $e) {
      echo 'Erreur PDO : '.$e->getMessage();
     echo '<br> Requete : '.$sql;
    }
    ?>
    


    Et oupsssss on dirait que c'est bien cette requête qui m'ennuie

    Message d'erreur:


    Erreur PDO : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 3
    Requete : INSERT INTO connectes (ip,timestamp) VALUES ('88.182.190.39',time())
    1. Bon j'ai préparé le code pour faire un fichier externe, je vais le faire après.

      Sortir les requêtes de leur exécution ne me donnent aucune erreur mais par contre l'echo n'affiche rien.

      J'ai réparé une autre erreur de '

      Maintenant avec ce code (compteur de visiteurs), je n'ai plus de page blanche et j'ai un résultat de 0 au lieu de 1 au minimum. Impossible d'avoir 0 puisque qu'il y a moi qui est sur la page.

      La requête INSERT ne fonctionne pas, j'ai vérifié sur la BDD et en effet je ne suis pas comptabilisé...

      Ça doit pas être grand chose ?

      Merci d'avance pour la dernière ligne droite ;)

      Je t'ai mis le code en entier

      <?php
      try 
      {
      $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
      $connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      } catch(PDOException $e) 
      {
      echo 'Erreur PDO : '.$e->getMessage();
      }
      ?>
      <?php
      // ÉTAPE 1 : on vérifie si l'IP se trouve déjà dans la table.
      // Pour faire ça, on n'a qu'à compter le nombre d'entrées dont le champ "ip" est l'adresse IP du visiteur.
      $retour = $connexion->query("SELECT COUNT(*) AS nbre_entrees FROM connectes WHERE ip='".$_SERVER['REMOTE_ADDR']."'");
      $donnees = $retour ->fetch();
      
      
      if ($donnees['nbre_entrees'] == 0) // L'IP ne se trouve pas dans la table, on va l'ajouter.
      {$connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES ('".$_SERVER['REMOTE_ADDR']."','time()')");}
      
      
      else // L'IP se trouve déjà dans la table, on met juste à jour le timestamp.
      {$connexion->exec("UPDATE connectes SET timestamp=' . time() . ' WHERE ip='".$_SERVER['REMOTE_ADDR']."'");}
      
      
      // ÉTAPE 2 : on supprime toutes les entrées dont le timestamp est plus vieux que 5 minutes.
      // On stocke dans une variable le timestamp qu'il était il y a 5 minutes :
      $timestamp_5min = time() - (60 * 5); // 60 * 5 = nombre de secondes écoulées en 5 minutes
      $connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);
      
      
      // ÉTAPE 3 : on compte le nombre d'IP stockées dans la table. C'est le nombre de visiteurs connectés.
      $retour = $connexion->query("SELECT COUNT(*) AS nbre_entrees FROM connectes");
      $donnees = $retour->fetch();
      $nb = $donnees['nbre_entrees'];
      ?>
      <?php echo "Actuellement, ".$nb." visiteur(s)"; ?>
      
      1. Modérateur
        Tant que tu ne sortiras pas les requêtes des executions... je n'irai pas plus loin avec toi !

        Le fait de sortir les requêtes... permet d'en faire des ECHO ... puis... d'aller, grâce à ces ehco.. les tester directement dans ta BDD (via un simple copié / collé ) !

        NB : Time() est une fonction ... il ne faut pas lui mettre de quotes autour !
      2. Modérateur
        Et puis rajoutes cette ligne de code
        error_reporting(E_ALL);
        

        Au tout début de ta page... ça affichera les éventuelles erreurs de code....
    2. Je viens d'essayer ton code et echo n'affiche rien mais la page s'affiche.

      Je remet le code en entier et page blanche...

      Au lieu de me mettre un message d'erreur c'est page blanche, dur dur !

      try {
      	
      $connexion = new PDO("");
      $connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      
      
      $retour = $connexion->query("SELECT COUNT(*) AS nbre_entrees FROM connectes WHERE ip='".$_SERVER['REMOTE_ADDR']."'");
      $donnees = $retour ->fetch();
      
      if ($donnees['nbre_entrees'] == 0)
      {
      $connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES ('".$_SERVER['REMOTE_ADDR']."',time())";	
      }
      else{			
      $connexion->exec("UPDATE connectes SET timestamp=' . time() . ' WHERE ip='".$_SERVER['REMOTE_ADDR']."'");}
      $timestamp_5min = time() - (60 * 5);
      $connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);
      
      $retour = $connexion->query("SELECT COUNT(*) AS nbre_entrees FROM connectes");
      $columns = $retour->fetch();
      $nb = $columns['nbre_entrees'];
      echo "".$nb."";
      
      } catch(PDOException $e) {
          echo 'Erreur PDO : '.$e->getMessage();
      }
      ?>
      
      1. Modérateur
        Tu n'as pas essayé mon code ... !!
        - Pourquoi as tu toujours les infos de connexion dans la même page que le reste de ton code ?
        - Pourquoi n'as tu pas sorti les requêtes de leur exécution ?
    3. Je te remercie des conseils je vais décomposer ainsi

      $connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES (:".$_SERVER['REMOTE_ADDR'].",:.time().)");


      Je croie qu'il ne reste plus qu'une erreur sur ce code

      Un problème de ' ou "...

      Je comprends rien ça doit être l'histoire des : ?
      1. Modérateur
        C'est surtout que ..... que viennent faire les ":" devant tes variables ???
        ce n'est utilisé que dans le cas de requêtes préparées ... hors... toi tu ne lesutilises pas !

        $sql = "INSERT INTO connectes 
                                   (ip,timestamp) 
                    VALUES ('".$_SERVER['REMOTE_ADDR']."',time())";
        
        try {
           $connexion->exec($sql);
        } catch(PDOException $e) {
          echo 'Erreur PDO : '.$e->getMessage();
        	echo '<br> Requete : '.$sql;
        }
        
        
    4. Modérateur
      Bonjour,

      Déjà... mets les infos de connexion à ta BDD dans un fichier à part qu'il te suffira d'inclure dans les pages où tu en as besoin.
      Pas besoin de le recopier 50 fois dans ton code !

      Ensuite... sépare les requêtes .. de leur exécution.
      Ca permet d'en faire un ECHO au cas où .. et ainsi de pouvoir les tester en direct dans ta BDD pour trouver la/les erreur(s).

      par exemple :
      <?php
      //------------------------------------------//
      // Fichier de connexion à la BDD
      //  cnxBDD.php
      //------------------------------------------//
      $host = '12345';
      $dbname = '12345';
      $user = '12345';
      $pwd = '12345';
      
      try {
       $connexion = new PDO("mysql:host=".$host.";dbname=."$dbname.";charset=utf8", $user, $pwd);
      } catch(PDOException $e) {
        echo 'Erreur PDO : '.$e->getMessage();
      }
      
      ?>
      


      <?php
      
      // On inclus le fichier de connexion à la BDD
      require_once "cnxBDD.php";
      
      try {
        $sql = "SELECT COUNT(*) AS nbre_entrees 
                    FROM connectes 
                   WHERE ip='".$_SERVER['REMOTE_ADDR']."'";
        $retour = $connexion->query($sql);
        $donnees = $retour ->fetch();
      } catch(PDOException $e) {
        echo 'Erreur PDO : '.$e->getMessage();
      	echo '<br> Requete : '.$sql;
      }
      
      
      


      1. ok donc c'est, par exemple:

        query("SELECT

        ou

        query('SELECT

        ?

        Je vais essayer de revoir toutes les lignes merci de ton aide c'est sympa
        1. Il ne s'agit plus de la même requête. Maintenant c'est
          $connexion->exec("UPDATE connectes SET timestamp=' . time() . ' WHERE ip=".$_SERVER['REMOTE_ADDR']);

          qui ne passe pas car tu as mélangé les ' et les ". Ce n'est pas un problème de requête ou de PDO, tu as un problème avec l'écriture des chaînes en PHP.
          1. Le message d'erreur a rétrécie :)

            Erreur PDO : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(). WHERE ip=88.182.190.39' at line 1

            $retour = $connexion->query("SELECT COUNT(*) AS nbre_entrees FROM connectes WHERE ip='".$_SERVER['REMOTE_ADDR']."'");
            
            1. Même erreur

              Erreur PDO : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*) AS nbre_entrees FROM connectes WHERE ip='88.182.190.39'' at line 1
              1. Cool ! maintenant le page s'affiche avec le message d'erreur suivant:

                Erreur PDO : SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*) AS nbre_entrees FROM connectes WHERE ip=88.182.190.39' at line 1

                On dirait que ça bloque sur une erreur de syntaxe dans l'une des requettes... On avance merci beaucoup Firoxyd
                1. Si ip est une chaine dans la base, il faut des quotes autour:
                  $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip='".$_SERVER['REMOTE_ADDR']."'");
                  
                  
              2. Page blanche...

                Tant que $donnees = $retour ->fetch(); ou $columns = $retour->fetch(); est dans le code, c'est page blanche assurée !

                Trop bizarre le PDO

                <?php
                try {
                	
                $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
                
                $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
                $donnees = $retour ->fetch();
                if ($donnees['nbre_entrees'] == 0){
                $connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES (:".$_SERVER['REMOTE_ADDR'].",:.time().)");}
                else{			
                $connexion->exec("UPDATE connectes SET timestamp=.time(). WHERE ip=".$_SERVER['REMOTE_ADDR']);}
                
                $timestamp_5min = time() - (60 * 5);
                $connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);
                
                $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
                $columns = $retour->fetch();
                var_dump($columns);
                $nb = $columns['nbre_entrees'];
                echo "".$nb."";
                
                } catch(PDOException $e) {
                    echo 'Erreur PDO : '.$e->getMessage();
                }
                ?>
                
                1. Essai avec
                  $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
                  $connexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                  ...
                  
              3. Page blanche...

                Voila le nouveau code:

                try {
                	
                $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
                
                $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
                $donnees = $retour ->fetch();
                if ($donnees['nbre_entrees'] == 0){
                $connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES (:".$_SERVER['REMOTE_ADDR'].",:.time().)");}
                else{			
                $connexion->exec("UPDATE connectes SET timestamp=.time(). WHERE ip=".$_SERVER['REMOTE_ADDR']);}
                
                $timestamp_5min = time() - (60 * 5);
                $connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);
                
                $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
                $columns = $retour->fetch();
                $nb = $columns['nbre_entrees'];
                echo "".$nb."";
                
                } catch(PDOException $e) {
                    echo 'Erreur PDO : '.$e->getMessage();
                }
                
                1. Tu peux essayer de debuger en ajoutant des var_dump pour vérifier ce que contiennent tes variables.

                  Par exemple cela nous indiquera ce qu'il y a réellement dans $columns :
                  $columns = $retour->fetch();
                  var_dump($columns);
                  $nb = $columns['nbre_entrees'];
                  
              4. J'ai toujours une page blanche

                Merci Firoxyd

                Je remets le nouveau code en entier

                <?php	
                try {
                	
                $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
                
                $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
                $donnees = $retour ->fetch();
                if ($donnees['nbre_entrees'] == 0){
                $connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES (:".$_SERVER['REMOTE_ADDR'].",:.time())");}
                else{			
                $connexion->exec("UPDATE connectes SET timestamp=' . time() . ' WHERE ip=".$_SERVER['REMOTE_ADDR']);}
                
                $timestamp_5min = time() - (60 * 5);
                $connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);
                
                $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
                $columns = $retour->fetch();
                $nb = $columns['nbre_entrees'];
                echo "".$nb."";
                
                } catch(PDOException $e) {
                    echo 'Erreur PDO : '.$e->getMessage();
                }
                ?>
                
                1. Merci de ton aide.

                  J'ai une page blanche :(

                  Voici le nouveau code:

                  <?php 
                  
                  try {
                   
                  $connexion = new PDO("mysql:host=12345;dbname=12345;charset=utf8", "12345", "12345");
                  
                  $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
                  $donnees = $connexion->query($retour);
                  if ($donnees['nbre_entrees'] == 0){
                  $connexion->exec("INSERT INTO connectes (ip,timestamp) VALUES (:".$_SERVER['REMOTE_ADDR'].",:.time())");}
                  else{   
                  $connexion->exec("UPDATE connectes SET timestamp=' . time() . ' WHERE ip=".$_SERVER['REMOTE_ADDR']);}
                  
                  $timestamp_5min = time() - (60 * 5);
                  $connexion->exec("DELETE FROM connectes WHERE timestamp < ".$timestamp_5min);
                  
                  $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
                  $columns = $retour->fetch();
                  $nb = $columns['nbre_entrees'];
                  echo "".$nb."";
                  
                  } catch(PDOException $e) {
                      echo 'Erreur PDO : '.$e->getMessage();
                  }
                  ?>
                  
                  1. Il ne te manquerait pas un fetch par là ?
                    $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
                    $donnees = $connexion->query($retour);
                    if ($donnees['nbre_entrees'] == 0){
                    


                    $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes WHERE ip=".$_SERVER['REMOTE_ADDR']);
                    $donnees = $retour ->fetch();
                    if ($donnees['nbre_entrees'] == 0){
                    
                2. Salut,

                  Je ne comprends pas
                  $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
                  $donnees = $connexion->query($retour);
                  $columns = $donnees->fetch();
                  

                  Pourquoi deux queries ?
                  Tu as essayé comme ceci ?
                  $retour = $connexion->query("SELECT COUNT (*) AS nbre_entrees FROM connectes");
                  $columns = $retour->fetch();