Résolu [RESOLUE][PHP] Soucis de rowCount avec PDO

Solutions (18)
Tags :
  • Php
  • Connexion
  • MySQL
  • Programmation
|
Bonjour, voila j'ai fait un site qui fonctionnait parfaitement avec les commandes du genre mysql_query, seulement j'ai voulu le passé a la PDO car cela est mieux plus sécurisé et autre.
Seulement j'ai quelque petits soucis comme celui que je vais vous montrer où la PDO plante et où mysql_ fonctionne.
Ici quand je demande directement a la base de donnée la requête sql tout fonctionne bien, quand je fait avec mysql_query tout fonctionne bien mais ici ça ne fonctionne pas qu'est-ce qui est mal fait ? :(  (ma connexion est bien effectué et fonctionne bien sur d'autre endroit)


voici mon code actuel :

  1. <?php
  2. include ("./includes/identifiants.php");
  3. $query=$db->query('SELECT site_topic.topic_id, topic_titre, topic_createur, topic_vu, topic_post, topic_time, topic_last_post,
  4. Mb.membre_pseudo AS membre_pseudo_createur, post_id, post_createur, post_time, Ma.membre_pseudo AS membre_pseudo_last_posteur FROM site_topic
  5. LEFT JOIN site_membres Mb ON Mb.membre_id = site_topic.topic_createur
  6. LEFT JOIN site_post ON site_topic.topic_last_post = site_post.post_id
  7. LEFT JOIN site_membres Ma ON Ma.membre_id = site_post.post_createur
  8. WHERE topic_genre <> "Annonce" AND site_topic.site_id = "'.$site.'"
  9. ORDER BY topic_last_post DESC
  10. LIMIT '.$premierMessageAafficher.' ,'.$nombreDeMessagesParPage);
  11.  
  12. if ($query->rowCount() > 0)
  13. {
  14. ?>
  15. <table>
  16. <tr>
  17. <th><img src="./css/img/message.gif" alt="Message" /></th>
  18. <th class="titre"><strong>Titre</strong></th>
  19. <th class="nombremessages"><strong>Réponses</strong></th>
  20. <th class="nombrevu"><strong>Vus</strong></th>
  21. <th class="auteur"><strong>Auteur</strong></th>
  22. <th class="derniermessage"><strong>Dernier message </strong></th>
  23. </tr>
  24. <?php
  25. while ($data = $query->fetch())
  26. {
  27.  
  28. echo'<tr><td><img src="./css/img/message.gif" alt="Message" /></td>
  29.  
  30. <td class="titre">
  31. <strong><a href="./voirtopic.php?t='.$data['topic_id'].'"
  32. title="Topic commencé à
  33. '.date('H\hi \l\e d M,y',$data['topic_time']).'">
  34. '.stripslashes(htmlspecialchars($data['topic_titre'])).'</a></strong></td>
  35.  
  36. <td class="nombremessages">'.$data['topic_post'].'</td>
  37.  
  38. <td class="nombrevu">'.$data['topic_vu'].'</td>
  39.  
  40. <td><a href="./voirprofil.php?m='.$data['topic_createur'].'
  41. &action=consulter">
  42. '.stripslashes(htmlspecialchars($data['membre_pseudo_createur'])).'</a></td>';
  43. $query->CloseCursor();
  44. $query=$db->prepare('SELECT config_valeur FROM site_config WHERE config_nom=:post');
  45. $query->execute(array(
  46. 'post' => "post_par_page"
  47. ));
  48. $donnee=$query->fetch();
  49. $nombreDeMessagesParPage = $donnee['config_valeur'];
  50. $nbr_post = $data['topic_post'] +1;
  51. $page = ceil($nbr_post / $nombreDeMessagesParPage);
  52.  
  53. echo '<td class="derniermessage">Par
  54. <a href="./voirprofil.php?m='.$data['post_createur'].'
  55. &action=consulter">
  56. '.stripslashes(htmlspecialchars($data['membre_pseudo_last_posteur'])).'</a><br />
  57. A <a href="./voirtopic.php?t='.$data['topic_id'].'&page='.$page.'#p_'.$data['post_id'].'">'.date('H\hi \l\e d M y',$data['post_time']).'</a></td></tr>';
  58.  
  59. }
  60. ?>
  61. </table>
  62. <?php
  63. }
  64. else
  65. {
  66. echo'<p>Ce site ne contient aucun sujet actuellement</p>';
  67. }
  68. $query->CloseCursor();
  69. ?>


Voila, et cela ne fonctionne pas j'ai le message comme quoi il n'y a pas de sujet..



Merci d'avance !
Contenus similaires
Meilleure solution
partage
|
Sinon tu peux faire :

  1. $row = $query->fetchAll();
  2.  
  3. if (count($row) > 0)
  4. {
  5.  
  6. // ...
  7.  
  8. foreach($row as $data){
  9. // ...
  • Commenter cette solution |
Score
0
òh
òi
, Ex-AdMiN |
Nexys a dit :
J'aimerais bien le comprendre quand même ^^
Même si cela peut ne pas m'aider ici il m'aidera peut être plus tard ^^


Pour comprendre il faut comprendre un peu comment fonctionne MySQL, les requêtes préparées ainsi que le Query Cache.

Lorsqu'on fait une requête préparées le principe est d'envoyer un modèle de requête, MySQL fait l'optimisation sur la façon générique dont il va résoudre le problème, puis les paramètres sont envoyés (bindValue()) et c'est plus rapide.

Le query cache lui est particulièrement efficace pour les petits résultats sur des tables qui sont peu modifiée. Le principe de base est le suivant, je fait un SELECT COUNT(*) FROM toto WHERE nom='tata', la probabilité d'avoir le même résultat si la table n'a pas été modifée est énorme, je met donc en cache le résultat au cas où je refasse la requête.

Imaginons une requête qui ferait SELECT COUNT(DISTINCT toto.id) FROM toto NATURAL JOIN tata NATURAL JOIN tutu WHERE tutu.nom='tutu'. La probabilité si le volume de donnée est important que la requête soit longue est très importante. Cependant si tu tests, la deuxième exécution immédiatement après de la requête, le résultat arrive immédiatement (normalement). C'est le query cache de MySQL. En revanche tu fais la même requête avec un prepare() la seconde requête sera lente. En revanche c'est assez malin de le faire pour des gros résultat car le query cache est petit, il peut donc pas stcoker un gros résultat, donc il n'y a pas de query cache, dont autant utilise l'optimisation faite lors du prepare() ...

Bref, c'est pas simple d'expliquer sur un forum.


  • Commenter cette réponse |
Score
0
òh
òi
|
Meilleure réponse sélectionnée par Nexys.
  • Commenter cette réponse |
Score
0
òh
òi
|
Désolé du double post, j'ai apporté des corrections et maintenant je compte bien mes 2 topics seulement ils ne s'affichent pas :( 



Voici un de mes deux cas, le deuxième étant similaire...
  1. include ("./includes/identifiants.php");
  2.  
  3. $query=$db->prepare('SELECT site_topic.topic_id, topic_titre, topic_createur, topic_vu, topic_post, topic_time, topic_last_post,
  4. Mb.membre_pseudo AS membre_pseudo_createur, post_id, post_createur, post_time, Ma.membre_pseudo AS membre_pseudo_last_posteur FROM site_topic
  5. LEFT JOIN site_membres Mb ON Mb.membre_id = site_topic.topic_createur
  6. LEFT JOIN site_post ON site_topic.topic_last_post = site_post.post_id
  7. LEFT JOIN site_membres Ma ON Ma.membre_id = site_post.post_createur
  8. WHERE topic_genre <> "Annonce" AND site_topic.site_id = :site
  9. ORDER BY topic_last_post DESC
  10. LIMIT :premier ,:nombre');
  11. $query->bindValue(':site',$site,PDO::PARAM_INT);
  12. $query->bindValue(':premier',(int) $premierMessageAafficher,PDO::PARAM_INT);
  13. $query->bindValue(':nombre',(int) $nombreDeMessagesParPage,PDO::PARAM_INT);
  14. $query->execute();
  15.  
  16. if ($query->fetchColumn() > 0)
  17. {
  18. ?>
  19. <table>
  20. <tr>
  21. <th><img src="./css/img/message.gif" alt="Message" /></th>
  22. <th class="titre"><strong>Titre</strong></th>
  23. <th class="nombremessages"><strong>Réponses</strong></th>
  24. <th class="nombrevu"><strong>Vus</strong></th>
  25. <th class="auteur"><strong>Auteur</strong></th>
  26. <th class="derniermessage"><strong>Dernier message </strong></th>
  27. </tr>
  28. <?php
  29. while ($data=$query->fetchAll())
  30. {
  31.  
  32. echo'<tr><td><img src="./css/img/message.gif" alt="Message" /></td>
  33.  
  34. <td class="titre">
  35. <strong><a href="./voirtopic.php?t='.$data['topic_id'].'"
  36. title="Topic commencé à
  37. '.date('H\hi \l\e d M,y',$data['topic_time']).'">
  38. '.stripslashes(htmlspecialchars($data['topic_titre'])).'</a></strong></td>
  39.  
  40. <td class="nombremessages">'.$data['topic_post'].'</td>
  41.  
  42. <td class="nombrevu">'.$data['topic_vu'].'</td>
  43.  
  44. <td><a href="./voirprofil.php?m='.$data['topic_createur'].'
  45. &action=consulter">
  46. '.stripslashes(htmlspecialchars($data['membre_pseudo_createur'])).'</a></td>';
  47. $query->CloseCursor();
  48. $query=$db->prepare('SELECT config_valeur FROM site_config WHERE config_nom=:post');
  49. $query->execute(array(
  50. 'post' => "post_par_page"
  51. ));
  52. $donnee=$query->fetch();
  53. $nombreDeMessagesParPage = $donnee['config_valeur'];
  54. $nbr_post = $data['topic_post'] +1;
  55. $page = ceil($nbr_post / $nombreDeMessagesParPage);
  56.  
  57. echo '<td class="derniermessage">Par
  58. <a href="./voirprofil.php?m='.$data['post_createur'].'
  59. &action=consulter">
  60. '.stripslashes(htmlspecialchars($data['membre_pseudo_last_posteur'])).'</a><br />
  61. A <a href="./voirtopic.php?t='.$data['topic_id'].'&page='.$page.'#p_'.$data['post_id'].'">'.date('H\hi \l\e d M y',$data['post_time']).'</a></td></tr>';
  62.  
  63. }
  64. ?>
  65. </table>
  66. <?php
  67. }
  • Commenter cette réponse |
Score
0
òh
òi
|
Désolé, je n'ai pas eu le temps de répondre ce matin, j'ai essayé la solution de Seb mais cela ne fonctionne pas non plus je finis par désespéré..
  • Commenter cette réponse |
Score
0
òh
òi
|
J'aimerais bien le comprendre quand même ^^
Même si cela peut ne pas m'aider ici il m'aidera peut être plus tard ^^
  • Commenter cette réponse |
Score
0
òh
òi
, Ex-AdMiN |
C'est pas grave, c'était intéressant pourtant :D 
  • Commenter cette réponse |
Score
0
òh
òi
|
Je n'ai pas tellement compris ton message SIM07 :/ 
  • Commenter cette réponse |
Score
0
òh
òi
, Ex-AdMiN |
Pour info, pour le COUNT(*) c'est bien d'utiliser PDO::query() (si les paramètres sont parfaitement sûr) en revanche pour la récupération des résultats il est préférable d'utiliser passer par PDO::p repare() et un PDOStatement pour les performances. Car dans le premier cas la requête va facilement aller en query cache et la seconde est lourde et longue à optimiser.

Dans ton cas, personnellement je n'hésiterais pas trop, si $nombreDeMessagesParPage ne peut pas être trop gros de faire un PDOStatement::fetchAll() car tu ferais bien de séparer un peu la logique de tes templates,,; mélanger logique et code HTML cela devient vite illisible.
  • Commenter cette réponse |
Score
0
òh
òi
|
J'avais déjà essayé sans aucun succès... Ca ne fonctionne toujours pas, j'ai tester ma requête directement dans la BDD et il me sort bien la ligne que je veux mais pas en php
  • Commenter cette réponse |
Score
0
òh
òi
|
Mais non, le truc important est if ($res->fetchColumn() > 0) {
Ou dans ton cas, $query->fetchColumn().
  • Commenter cette réponse |
Score
0
òh
òi
|
Le problème c'est que je me vois ma placé un COUNT(*) dans une requête pareil


  1. # $query=$db->query('SELECT site_topic.topic_id, topic_titre, topic_createur, topic_vu, topic_post, topic_time, topic_last_post,
  2. # Mb.membre_pseudo AS membre_pseudo_createur, post_id, post_createur, post_time, Ma.membre_pseudo AS membre_pseudo_last_posteur FROM site_topic
  3. # LEFT JOIN site_membres Mb ON Mb.membre_id = site_topic.topic_createur
  4. # LEFT JOIN site_post ON site_topic.topic_last_post = site_post.post_id
  5. # LEFT JOIN site_membres Ma ON Ma.membre_id = site_post.post_createur
  6. # WHERE topic_genre <> "Annonce" AND site_topic.site_id = "'.$site.'"
  7. # ORDER BY topic_last_post DESC
  8. # LIMIT '.$premierMessageAafficher.' ,'.$nombreDeMessagesParPage);
  • Commenter cette réponse |
Score
0
òh
òi
|
Le FOUND_ROWS() est, à mon avis, une mauvaise idée car il nécessite d'avoir un SQL_CALC_FOUND_ROWS dans la requête.
Le plus simple est de lire la doc qu'a donnée OmaR, qui indique (exemple 2):
Citation :
For most databases, PDOStatement::rowCount() does not return the number of rows affected by a SELECT statement. Instead, use PDO::query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement::fetchColumn() to retrieve the number of rows that will be returned. Your application can then perform the correct action.


  1. <?php
  2. $sql = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
  3. if ($res = $conn->query($sql)) {
  4.  
  5. /* Check the number of rows that match the SELECT statement */
  6. if ($res->fetchColumn() > 0) {
  7.  
  8. /* Issue the real SELECT statement and work with the results */
  9. $sql = "SELECT name FROM fruit WHERE calories > 100";
  10. foreach ($conn->query($sql) as $row) {
  11. print "Name: " . $row['NAME'] . "\n";
  12. }
  13. }
  14. /* No rows matched -- do something else */
  15. else {
  16. print "No rows matched the query.";
  17. }
  18. }
  19.  
  20. $res = null;
  21. $conn = null;
  22. ?>
  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
et t'es sûre que ta requête te renvoi quelque chose ?
  • Commenter cette réponse |
Score
0
òh
òi
|
Oui c'était avec un SELECT, et même avec ta solution ca ne fonctionne pas...
  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
Avec un SELECT aussi ?
Et je t'ai mis l'exemple, tu remplaces ton if($query->rowCount() > 0) par ce que je t'ai donné et ça devrait être bon
  • Commenter cette réponse |
Score
0
òh
òi
|
Le truc c'est que j'ai sur une autre page le même genre et cela fonctionne..

Je ne vois pas comment utilisé FOUND_ROWS() ...
  • Commenter cette réponse |
Score
0
òh
òi
, Modérateur |
Salut,

D'après la documentation (http://php.net/manual/en/pdostatement.rowcount.php) il semblerait que rowCount() ne soit utilisé que pour les commandes INSERT/DELETE/UPDATE.
Et que ce n'est pas obligatoire que rowCount() retourne le nombre de lignes lors d'un SELECT, et c'est le cas de MySQL qui ne retourne pas le nombre de lignes.
D'après la documentation de MySQL (http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows), il faut faire une autre requête de type SELECT FOUND_ROWS()
Exemple:
if ($db->query("SELECT FOUND_ROWS()")->fetchColumn() > 0)

  • Commenter cette réponse |

Ce n'est pas ce que vous cherchiez ?

Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS