Bonjour,
Je viens de me mettre à PDO et je me demandais si il existait un équivalent à mysql_num_rows() car je n'en vois pas dans la doc PHP.
Bien sur je pourrais utiliser une requête avec COUNT() mais ça oblige à faire une 2ème requête...
Merci
Bonjour,
Je viens de me mettre à PDO et je me demandais si il existait un équivalent à mysql_num_rows() car je n'en vois pas dans la doc PHP.
Bien sur je pourrais utiliser une requête avec COUNT() mais ça oblige à faire une 2ème requête...
Merci
Zend Certified PHP Engineer
« Crois-tu comprendre le monde juste en matant le 20H Ou connaître l'histoire en ayant lu que l'angle des vainqueurs ? » Keny Arkana
La doc préconise une 2e requête SELECT COUNT( ) http://fr.php.net/manual/en/pdostatement.rowcount.php
Autrement tu peux faire un count($statement->fetchAll( ))
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Au vu de la réponse de Sèb., je dirais que le plus rapide serait de faire une seconde requête avec un SELECT count()... parce que faire count($statement->fetchAll( )) puis un $statement->fetchAll( ) par la suite revient à faire deux fois la requête, qui si elle renvoit beaucoup de ligne peut ralentir considérablement le traitement.
Google est ton ami mais ton voisin aussi
Modérateur BI - Responsable Talend
Mes tutoriels - FAQ Talend - FAQ SQL*Plus
Avant toute chose : lire le mode d'emploi du forum et ses règles.
Suivez @Developpez sur twitter !
heu il faut evidemment recuperer le resultat du fetchAll()parce que faire count($statement->fetchAll( )) puis un $statement->fetchAll( )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $result = $sth->fetchAll(); $nbre = count($result); foreach ($result as $row) { }
N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP
Je pense que la méthode du fetchAll() est la mieux.
Parce que 2 requêtes, sur un serveur qui est déjà assez chargé je pense que ce n'est pas ce qu'il y a de mieux.
C'est vraiment dommage que le rowCount ne renvoi pas la valeur à tous les coups.
D'ailleurs il est écrit que pour certaines BDD, le nombre est renvoyé. Qu'en est il pour MySQL, la valeur est elle renvoyé ? Y a t il quelque chose à paramétrer pour que cela fonctionne ?
Zend Certified PHP Engineer
« Crois-tu comprendre le monde juste en matant le 20H Ou connaître l'histoire en ayant lu que l'angle des vainqueurs ? » Keny Arkana
Tout dépend de la requête.
Si vous faites de la pagination sur un très gros résultat, par exemple résultats 1-10, 11-20, ... 51-60... sur un total de 500 000 lignes, je vois mal faire un SELECT sur les 500000 lignes puis un count du fetchAll alors que l'on en affiche que 10 ! Dans ce cas il FAUT faire une deuxième requête SELECT COUNT(*), sinon le serveur de base de données et le réseau vont souffrir !
Par contre, si le résultat comporte peu de lignes toutes affichées à l'écran, là effectivement il vaut mieux faire un count sur le tableau renvoyé par fetchAll.
il existe tout simplement la méthode rowcount() applicable à l'objet ResultSet.
exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 <?php header("Content-Type: text/html; charset=UTF-8"); $cn = new PDO('mysql:host=localhost;dbname=cours','root',''); $rs = $cn->query('SELECT * FROM villes'); echo $rs->rowcount(); $cn = null; ?>
Oui mais la doc de PDOStatement::rowCount( ) précise :
... ce qui casse qque peu son intérêt.Si la dernière requête SQL exécutée par l'objet PDOStatement associé est une requête de type SELECT, quelques bases de données retourneront le nombre de lignes retournées par cette requête. Néanmoins, ce comportement n'est pas garanti pour toutes les bases de données et ne devrait pas être exécuté pour des applications portables.
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
rowCount est censé donner le nomber de lignes affectées, pas le nombre de lignes retournées par un SELECT.
En mysql, sous toute reserve, cela fonctionne aussi pour un SELECT, mais d'autres moteurs pourraient ne pas fonctionner ainsi.
N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP
bonjour,
vous avez entièrement raison.
J'ai relu mes notes sans aller vers la doc "officielle".
Par curiosité je suis allé faire quelques tests malheureusement très concluants.
Voici quelques remontées.
1 - MySQL natif : OK
2 - MySQL via ODBC : OK
3 - SYBASE via OBDC : OK
4 - MS-Access via ODBC : KO
5 - SQL Server via ODBC et pilote natif : KO
6 - SQL Server via mssql : triple KO (de toutes les façons MS recommande le passage via ODBC qui est KO)
7 - Oracle via ODBC : @+
8 - Oracle via natif : @+
Pour Oracle je ne l'ai pas sous la main aujourd'hui !
Je crois que le problème n'est pas tellement du SGBDR mais du pilote et de son paramétrage.
Quand nous aurons ??? des méthodes permettant de paramétrer les curseurs ce sera plus sûr.
Pour l'instant vous avez tous raison, un bon vieux SELECT COUNT(*) FROM ... vaut mieux que 2 tu l'auras :-)
Mis à part ça je reste un fan (modéré) de PDO parce ses performances sont vraiment très bonnes par rapport à des pear.DB ou pear.mbd2, ...
Bonne journée
Personnellement je fais comme indiqué : si j'ai besoin de connaitre le nombre d'enregistrement, je fais un fetchAll.
N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP
Ce qui est adapté lorsque l'on va de toute façon tout afficher, mais lorsque l'on a une recherche qui retourne potentiellement 500000 enregistrements, que l'on veut connaitre ce chiffre de 500000 mais n'en afficher que 10 ou 20 comme google, on ne va pas récupérer les 500000 lignes pour pouvoir les compter () : on fait un COUNT() pour obtenir 500000 et un SELECT qui ne récupère que les 10 ou 20 lignes, ce qui comme je le disais plus haut soulage le SGBD et le réseau.
La problème n'a pas changé depuis les extensions classiques alors.
Je ne pense pas qu'auparavant, tu faisais un SELECT de tous les enregistrements pour n'en afficher que 20.
N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP
Si tu veux dire que PDO n'apporte rien dans ce domaine par rapport aux anciennes extensions, c'est tout à fait ça.
Ce problème de comptage de résultat n'est pas anodin et dépend essentiellement du SGBD, pas de l'API.
Comme je le disais, la solution de tout récupérer (toutes les lignes et colonnes affichées) puis de les compter n'est pas valable dans le cas général, d'où la nécessité, pour schématiser, du SELECT COUNT avant le SELECT *...
Je maintiens ceci, mais je tiens également à souligner que les perfs du SELECT COUNT sont très variables selon les SGBD et selon les indexes mis en place.
MySQL est optimisé pour le SELECT COUNT (un des rares avantages de MySQL sur les autres SGBD, soit dit en passant), ce n'est donc pas très couteux.
Pour PostgreSQL ce n'est pas terrible et il est prévu une optimisation du COUNT mais je ne sais pas pour quand.
Oracle a le même pb que PostgreSQL actuellement : le COUNT est couteux et revient (presque) exactement à faire le SELECT * mais côté serveur uniquement (sans l'envoi des données vers le client effectué avec SELECT *, l'envoi de beaucoup de données étant également lourd pour le SGBD). Pourquoi le "presque" ? Parce qu'un COUNT(id) et des critères de recherche bien indexés peuvent n'entrainer que des balayages d'indexes, pas des enregistrements en eux-mêmes, ce qui est en général beaucoup plus rapide.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager