Remplacer msql par pdo

Bonjour,

J'essaie d'adapter mon script de news à PDO. Par exemple, j'ai remplacé :

if($archives != 'on') {
$req = "select id from ".$prefixe." WHERE valide!='inv'";
}
if($archives == 'on') {
$req = "select id from ".$prefixe." WHERE valide!='inv' AND date >= '".$datum."'";
}
$total = @mysql_num_rows($sql);
}
else $total = intval($_GET['total']);

// on determine debut du limit
$debut = ($page - 1) * $nb;


Par :

if($archives != 'on') {
$sql = $cnx->query("select id from ".$prefixe." WHERE valide!='inv'");
}
if($archives == 'on') {
$sql = $cnx->query("select id from ".$prefixe." WHERE valide!='inv' AND date >= '".$datum."'");
}

$total = $sql->fetchAll();
}
else $total = intval($_GET['total']);

// on determine debut du limit
$debut = ($page - 1) * $nb;


Mais j'ai un message d'erreur : "Unsupported operand types" à la ligne 148, la voici :

// calcul du nombre de pages
		 $nbpages = ceil($total / $nb); // arrondi a l'entier superieur


C'est pour le calcul du nombre de news et sa pagination.

16 réponses

  1. bonsoir,

    les codes que tu donnes ne sont pas clair et ça ne sert pas a grand chose de remplacer les fonctions mysql par pdo si tu n'utilises pas les requêtes préparé

    par exemple

    $pdo = new PDO();
    $req = $pdo->prepare('SELECT ....WHERE id = :variable LIMIT 1');
    $req->execute(array('variable' => $id));
    $data = $req->fetch(PDO::FETCH_OBJ);
    $req->closeCursor();


    c'est un exemple d'utilisation de pdo. il faut toujours préparer ses requêtes, rien que pour éviter les injections sql
    1. Donc, si j'ai bien compris, une de mes requêtes doit donner ça :

      $id = intval($data['id']);
      $sql2 = $cnx->prepare("SELECT id FROM ".$prefixe."_comments WHERE news='$id'"); 
      $sql2->execute();
      $req = $cnx->query($sql2);  
      $res = $req->rowCount();


      Mais là, j'ai deux messages d'erreur :

      Warning: PDO::query() expects parameter 1 to be string, object given in /.../index.php on line 108

      Fatal error: Call to a member function rowCount() on a non-object in /.../index.php on line 109
      1. $id = intval($data['id']);
        $req = $cnx->prepare("SELECT id FROM ".$prefixe."_comments WHERE news= :id"); 
        $req->execute(array(':id' => $id));
        $res = $req->rowCount();
    2. Merci maka54,

      Maintenant, j'ai une autre erreur qui apparaît, mes news ne s'affichent pas :

      Warning: Division by zero in /.../index.php on line 150
      1. Warning: Division by zero in /.../index.php on line 150

        ligne 150 ??

        $nbpages = ceil( count($total) / $nb);

        cela veux dire que $nb = 0;
        1. il suffit d'ajouter
          if($nb == 0) $nb = 1;
          avant ta disvision

          même si ta page existe tu en as forcément une
          1. j'oublié intval sur l'id ne sert a rien en passant par prepare si le champ de ta table est en int la valeur est converti en int avant d'être testé c'est un des avantages de pdo
        2. J'ai essayé d'adapter à PDO ces requêtes, mais je n'y arrive pas, ce qui fait que mes news ne s'affichent pas :

          if($archives != 'off') {
          $sql = "SELECT *, DATE_FORMAT(date, '%d.%m.%Y') as date FROM ".$prefixe." WHERE valide!='inv' AND date >= '".$datum."' ORDER BY id $ordre LIMIT ".intval($debut).",".intval($nb);
          } else {
          $sql = "SELECT *, DATE_FORMAT(date, '%d.%m.%Y') as date FROM ".$prefixe." WHERE valide!='inv' ORDER BY id $ordre LIMIT ".intval($debut).",".intval($nb);
          }
          
          // parcours et affichage des résultats
          if($p = @mysql_query($sql,$c)){
          while($data = @mysql_fetch_array($p)){
          
          $sql2 = "SELECT * FROM ".$prefixe."_smileys";
          // on envoie la requête 
          $req2 = mysql_query($sql2) or die('Erreur SQL !<br>'.$sql2.'<br>'.mysql_error()); 
          while($resultat = mysql_fetch_array($req2)) {
          $data['texte'] = str_replace($resultat['code'],'<img src="'.$url.'admin/smileys/'.$resultat['url'].'" style="border:0"/>',$data['texte']);
          }
          
          1. J'avais cherché l'équivalent en PDO de mysql_query et mysql_fetch_array. J'avais fait ça :

            // parcours et affichage des résultats
            if($p = $cnx->query($sql,$c)){
            while($data = $p->fetch(PDO::FETCH_ASSOC));{


            et

            // on envoie la requête 
            $req2 = $cnx->query($sql2); 
            while($resultat = $req2->fetch(PDO::FETCH_ASSOC)) {
            1. Bonjour

              Ça n'a pas l'air si mal que ça. À condition d'enlever le ; en trop :
              while($data = $p->fetch(PDO::FETCH_ASSOC));{
              1. Ah oui, le ; n'était pas à sa place. Pourtant, ça ne marche pas, j'ai une erreur :

                Warning: PDO::query() [pdo.query]: SQLSTATE[HY000]: General error: mode must be an integer
                1. Sur quelle ligne as-tu cette erreur ? Sans doute celle-ci :
                  $cnx->query($sql,$c)

                  Qu'est-ce que c'est ce $c ? D'où sort-il ?
                  1. Je n'avais pas fait attention. Le $c, c'est la connexion à la bdd sous misql.
                    1. Est-ce que ça marche maintenant ?
                  2. Je me suis renseigné depuis sur des forums, j'en suis là :

                    // requete sql
                    if($archives != 'off') {
                    $sql = $cnx->prepare("SELECT *, DATE_FORMAT(date, '%d.%m.%Y') as date FROM ".$prefixe." WHERE valide!= ? AND date >= '".$datum."' ORDER BY id $ordre LIMIT ".intval($debut).",".intval($nb));
                    $sql->execute( array( 'inv' ) );
                    } else {
                    $sql = $cnx->prepare("SELECT *, DATE_FORMAT(date, '%d.%m.%Y') as date FROM ".$prefixe." WHERE valide!= ? ORDER BY id $ordre LIMIT ".intval($debut).",".intval($nb));
                    $sql->execute( array( 'inv' ) );
                    }
                    
                    // parcours et affichage des résultats
                    if($p = $cnx->query($sql)){
                    while($data = $p->fetch(PDO::FETCH_ASSOC)){


                    ça devrait marcher, et pourtant j'ai cette erreur :

                    Warning: PDO::query() expects parameter 1 to be string, object given...à cette ligne :

                    if($p = $cnx->query($sql)){


                    Merci de ton aide !
                    1. tu melange tout,

                      va voir comment fonctionne pdo, https://www.php.net/manual/fr/book.pdo.php

                      apres si tu as des questions, demande, mais je pense pas que tu t'es trop renseigné.

                      voici une requete pas à pas :

                      une requete préparée :
                      
                      $sql c'est ta requete (text brute)
                      $sql = "SELECT * FROM table WHERE id = :id";
                      
                      $cnx ets ton instance pdo
                       tu te connecte à l'instance pdo puis prepare ta requete
                      $req = $cnx->prepare( $sql ); 
                      
                      $req est le resultat qu'il faut executer avec la valeur du parametre dans prepare ( :id )
                      $req->execute(array(':id' => $id));
                      
                      seulement maintenant, tu recupere les données
                      while($data = $req->fetch(PDO::FETCH_ASSOC)){
                      
                      }
                      
                      une requete simple : (sans parametre)
                      
                      $sql c'est ta requete (text brute)
                      $sql = "SELECT * FROM table ";
                      
                      tu peux faire query directement sans prepare ni execute
                      $req = $cnx->query($sql)
                  3. Avec une requête simple, ça marche, mes news s'affichent. J'avais compris qu'il fallait obligatoirement préparer ses requêtes pour éviter les injections sql.
                    1. si tu prépare tes requêtes de cette facon

                      $rq = $pdo->prepare('SELECT * FROM table WHERE id=\''.$id.'\' LIMIT 1');

                      tu n'évite en rien les injections sql

                      par contre si tu prépare ta requête comme ça

                      $rq = $pdo->prepare(SELECT * FROM table WHERE id = :id LIMIT 1);

                      là tu passes la valeur id est considéré comme une variable elle n'est plus simplement concaténé à la requête