Nombre de rangs avec AOP

il y a beaucoup de déclarations contradictoires autour. Quelle est la meilleure façon de compter les rangs en utilisant PDO en PHP? Avant D'utiliser AOP, j'ai simplement utilisé mysql_num_rows .

fetchAll est quelque chose que je ne veux pas parce que j'ai peut-être parfois affaire à de grands ensembles de données, donc pas bon pour mon utilisation.

avez-vous des suggestions?

158
demandé sur Sᴀᴍ Onᴇᴌᴀ 2009-05-19 19:12:30

21 réponses

$sql = "SELECT count(*) FROM `table` WHERE foo = bar"; 
$result = $con->prepare($sql); 
$result->execute(); 
$number_of_rows = $result->fetchColumn(); 

pas la façon la plus élégante de le faire, en plus il implique une requête supplémentaire.

AOP a PDOStatement::rowCount() , ce qui apparemment n'est pas travailler dans MySql. Quelle douleur.

de L'AOP Doc:

pour la plupart des bases de données, PDOStatement::rowCount() n'est pas retourne le nombre de lignes affectées par a SELECT statement. Au lieu de cela, utiliser AOP:: query () to issue a SELECT COMPTER(*) déclaration avec la même prédit comme votre choix prévu déclaration, puis utiliser PDOStatement:: fetchColumn () to récupérer le nombre de lignes être retourné. Votre application peut alors effectuer la bonne action.

éditer: l'exemple de code ci-dessus utilise une déclaration préparée, qui est dans de nombreux cas est probablement inutile dans le but de compter des lignes, donc:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;
221
répondu karim79 2013-12-30 14:50:25

comme je l'ai déjà écrit dans une réponse à une question similaire , la seule raison pour laquelle mysql_num_rows() a fonctionné est parce qu'il était à l'interne chercher toutes les rangées pour vous donner cette information, même si elle ne semble pas comme elle pour vous.

donc en AOP, vos options sont:

  1. utilisez la fonction FOUND_ROWS() de MySQL.
  2. utiliser les AOP fetchAll() fonction pour récupérer toutes les lignes dans un tableau, puis utiliser count() .
  3. faire une requête supplémentaire à SELECT COUNT(*) , comme karim79 suggéré.
77
répondu Chad Birch 2017-05-23 12:26:36

c'est super tard, mais j'ai rencontré le problème et je fais ceci:

function countAll($table){
   $dbh = dbConnect();
   $sql = "select * from `$table`";

   $stmt = $dbh->prepare($sql);
    try { $stmt->execute();}
    catch(PDOException $e){echo $e->getMessage();}

return $stmt->rowCount();

C'est vraiment simple et facile. :)

19
répondu Dan 2013-03-06 07:15:51

avant D'utiliser AOP, j'ai simplement utilisé mysql_num_rows() .

vous n'auriez pas dû l'utiliser en premier lieu.

mysql_num_rows() , ainsi que PDOStatement::rowCount() implique que vous déjà sélectionné vos données. Dans ce cas, il n'y a que deux cas d'utilisation possibles pour une telle fonction:

  1. vous sélectionniez vos données uniquement pour obtenir le nombre.
  2. vous voulez savoir si votre requête a retourné des lignes.

et le premier ne devrait jamais être utilisé du tout. il ne faut jamais sélectionner des lignes pour les Compter, car votre serveur peut en effet s'étouffer en raison de la grande série de données retournées.

de plus, sélectionner des lignes pour les Compter n'a tout simplement aucun sens. Une requête count(*) doit être exécutée à la place, avec une seule rangée retourner.

le second cas d'utilisation est moins désastreux mais plutôt inutile: dans le cas où vous avez besoin de savoir si votre requête a retourné des données, vous avez toujours les données elles-mêmes!

dites, Si vous sélectionnez une seule ligne, alors allez la chercher, et vérifiez le résultat:

$stmt->execute();
$row = $stmt->fetch();
if ($row) { // here! as simple as that
}

dans le cas où vous avez besoin d'obtenir de nombreuses lignes, alors vous pouvez utiliser fetchAll() .

fetchAll() est quelque chose que je ne veux pas car je peux parfois avoir affaire à de grands ensembles de données

notez que dans une application web, vous ne devriez jamais sélectionner un grand nombre de lignes. Seules les lignes qui seront effectivement utilisées sur une page web doit être sélectionné. À cet effet, une clause LIMIT ou similaire en SQL doit être utilisée. Et pour une telle quantité modérée de données, il est tout à fait juste d'utiliser fetchAll()

dans un tel cas rare quand vous avez besoin de sélectionner un réel énorme quantité de lignes (dans une application de console par exemple), pour réduire la quantité de mémoire utilisée, vous devez utiliser une requête , mais dans ce cas rowCount() ne sera pas disponible de toute façon , donc il n'y a pas d'utilisation pour cette fonction aussi bien.

donc, vous voyez, il n'y a pas de cas d'utilisation ni pour rowCount() ni pour une requête supplémentaire pour le remplacer, comme suggéré dans la réponse acceptée.

18
répondu Your Common Sense 2016-06-27 04:53:30

j'ai fini par utiliser ceci:

$result = $db->query($query)->fetchAll();

if (count($result) > 0) {
    foreach ($result as $row) {
        echo $row['blah'] . '<br />';
    }
} else {
    echo "<p>Nothing matched your query.</p>";
}
16
répondu Eric Warnke 2011-07-31 17:05:48

ce post est vieux mais obtenir le nombre de lignes en php avec AOP est simple""

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
7
répondu TenTen Peter 2014-07-23 00:31:06

C'est un vieux post, mais frustré à la recherche d'alternatives. Il est très regrettable que PDO ne dispose pas de cette fonctionnalité, d'autant plus que PHP et MySQL ont tendance à aller de pair.

il y a un défaut malheureux dans l'utilisation de fetchColumn() car vous ne pouvez plus utiliser ce jeu de résultats (effectivement) car fetchColumn() déplace l'aiguille à la rangée suivante. Ainsi, par exemple, si vous avez un résultat semblable à

  1. Fruits - > Bananes
  2. Fruits - > Pomme
  3. Fruits - > Orange

si vous utilisez fetchColumn() vous pouvez découvrir qu'il y a 3 fruits retournés, mais si vous bouclez maintenant le résultat, vous n'avez que deux colonnes, le prix de fetchColumn() est la perte de la première colonne de résultats juste pour savoir combien de lignes ont été retournées. Cela conduit à un codage bâclé, et des résultats totalement erronés si mis en œuvre.

donc maintenant, en utilisant fetchColumn() vous devez mettre en œuvre et appel entièrement nouveau et la requête MySQL juste pour obtenir un nouveau jeu de résultats de travail. (qui, j'espère, n'a pas changé depuis votre dernière requête), je sais, peu probable, mais ça peut arriver. De plus, la charge des requêtes doubles sur la validation de tous les nombres de lignes. Qui pour cet exemple est petit, mais parsing 2 millions de lignes sur une requête jointe, pas un prix agréable à payer.

J'aime PHP et soutenir toutes les personnes impliquées dans son développement ainsi que la communauté dans son ensemble en utilisant PHP sur une base quotidienne, mais espère vraiment que c'est résolu dans les prochaines versions. C'est "vraiment" ma seule plainte avec PHP PDO, qui autrement est une grande classe.

5
répondu Eric 2010-07-14 02:29:47

répondre à cela parce que je me suis piégé avec elle en sachant maintenant ceci et peut-être qu'il sera utile.

gardez à l'esprit que vous ne pouvez pas obtenir des résultats deux fois. Vous devez sauvegarder le résultat fetch dans le tableau, obtenir le nombre de lignes par count($array) , et les résultats de sortie avec foreach . Par exemple:

$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);           
if (count($rows) > 0) {             
    foreach ($rows as $row) {
        //output your rows
    }                       
}
2
répondu csharp newbie 2014-08-10 06:01:44

si vous voulez juste obtenir un nombre de lignes (pas les données) ie. en utilisant COUNT (*) dans une déclaration préparée alors tout ce que vous devez faire est de récupérer le résultat et de lire la valeur:

$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql); 
$statement->execute(); 
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)

extraire toutes les lignes (données) pour effectuer un simple comptage est un gaspillage de ressources. Si le résultat est grand, votre serveur risque de s'étouffer.

1
répondu madfish 2016-06-11 09:16:24

Regardez ce lien: http://php.net/manual/en/pdostatement.rowcount.php Il n'est pas recommandé d'utiliser rowCount() dans les instructions SELECT!

1
répondu Reza Neghabi 2017-04-13 04:19:34

quand il s'agit de mysql comment compter ou obtenir combien de lignes dans une table avec PHP AOP j'utilise ce

// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);

// execute query
$stmt->execute();

// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];

les crédits vont à Mike @ codeofaninja.com

0
répondu Robert 2017-08-12 14:53:37

voici une extension personnalisée de la classe PDO, avec une fonction d'aide pour récupérer le nombre de lignes incluses par le critère" où " de la dernière requête.

vous pourriez avoir besoin d'ajouter plus de 'handlers', cependant, en fonction des commandes que vous utilisez. Pour l'instant, il ne fonctionne que pour les requêtes qui utilisent "FROM" ou "UPDATE ".

class PDO_V extends PDO
{
    private $lastQuery = null;

    public function query($query)
    {
        $this->lastQuery = $query;    
        return parent::query($query);
    }
    public function getLastQueryRowCount()
    {
        $lastQuery = $this->lastQuery;
        $commandBeforeTableName = null;
        if (strpos($lastQuery, 'FROM') !== false)
            $commandBeforeTableName = 'FROM';
        if (strpos($lastQuery, 'UPDATE') !== false)
            $commandBeforeTableName = 'UPDATE';

        $after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
        $table = substr($after, 0, strpos($after, ' '));

        $wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));

        $result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
        if ($result == null)
            return 0;
        return $result->fetchColumn();
    }
}
-1
répondu Venryx 2013-07-15 08:32:20

une doublure rapide pour obtenir la première entrée retournée. C'est agréable pour les requêtes très basiques.

<?php
$count = current($db->query("select count(*) from table")->fetch());
?>

référence

-1
répondu itsazzad 2013-10-02 12:57:19

j'ai essayé $count = $stmt->rowCount(); avec Oracle 11.2 et cela n'a pas fonctionné. J'ai décidé d'utiliser un pour boucle comme le montre ci-dessous.

   $count =  "";
    $stmt =  $conn->prepare($sql);
    $stmt->execute();
   echo "<table border='1'>\n";
   while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
        $count++;
        echo "<tr>\n";
    foreach ($row as $item) {
    echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):"&nbsp;")."</td>\n";
        } //foreach ends
        }// while ends
        echo "</table>\n";
       //echo " no of rows : ". oci_num_rows($stmt);
       //equivalent in pdo::prepare statement
       echo "no.of rows :".$count;
-1
répondu manas mukherjee 2014-12-21 11:02:52

pour les requêtes simples où je veux une ligne spécifique, et que je veux savoir si elle a été trouvée, j'utilise quelque chose comme:

function fetchSpecificRow(&$myRecord) {
    $myRecord = array();
    $myQuery = "some sql...";
    $stmt = $this->prepare($myQuery);
    $stmt->execute(array($parm1, $parm2, ...));
    if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
    return $myErrNum;
}
-1
répondu user5862537 2016-01-31 00:20:49

function count_x ($connect) { $query = "SELECT * FROM tbl WHERE id = '0'"; $statement = $connect - >prepare ($query); $statement - >execute (); $total_rows = $statement->rowCount (); return $total_rows;}

-1
répondu alpazull 2018-04-11 06:22:05

quand vous faites un compte (*) dans votre déclaration mysql comme dans

$q = $db->query("SELECT COUNT(*) FROM ...");

votre requête mysql compte déjà le nombre de résultats pourquoi Compter à nouveau en php? pour obtenir le résultat de votre mysql

$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;

et $nb contiendront l'entier que vous avez compté avec votre déclaration mysql un peu long à écrire, mais rapide à exécuter

Edit: désolé pour le mauvais post mais comme un certain exemple montrer la requête avec le nombre dans, je suggérais d'utiliser le résultat mysql, mais si vous n'utilisez pas le nombre dans sql fetchAll() est efficace, si vous sauvegardez le résultat dans une variable, vous ne perdrez pas une ligne.

$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);

count($table) retournera le nombre de ligne et vous pouvez toujours utiliser le résultat après comme $row = $table[0] ou en utilisant un foreach

foreach($table as $row){
  print $row->id;
}
-2
répondu Surpriserom 2013-05-30 09:31:24

vous pouvez combiner la meilleure méthode en une ligne ou une fonction, et avoir la nouvelle requête générée automatiquement pour vous:

function getRowCount($q){ 
    global $db;
    return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}

$numRows = getRowCount($query);
-2
répondu Bryan 2016-05-26 23:25:21
$qry = "select * from tabel";
$cmd = $conn->prepare($qry);
$cmd->execute();
$cmd->rowCount()
-2
répondu Dika Purnasucita 2016-05-31 06:10:03
<table>
      <thead>
           <tr>
                <th>Sn.</th>
                <th>Name</th>
           </tr>
      </thead>
      <tbody>
<?php
     $i=0;
     $statement = $db->prepare("SELECT * FROM tbl_user ORDER BY name ASC");
     $statement->execute();
     $result = $statement->fetchColumn();
     foreach($result as $row) {
        $i++;
    ?>  
      <tr>
         <td><?php echo $i; ?></td>
         <td><?php echo $row['name']; ?></td>
      </tr>
     <?php
          }
     ?>
     </tbody>
</table>
-2
répondu Amranur Rahman 2017-01-09 09:45:36

paramètre D'utilisation array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL) , sinon afficher -1:

Usen parametro array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL) , le péché ello vente -1

exemple:

$res1 = $mdb2->prepare("SELECT clave FROM $tb WHERE id_usuario='$username' AND activo=1 and id_tipo_usuario='4'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$res1->execute();

$count=$res1->rowCount();
echo $count;
-3
répondu Victor Idrogo Aliaga 2016-03-23 23:46:28