web-dev-qa-db-fra.com

Nombre de lignes avec AOP

Il y a beaucoup de déclarations contradictoires autour. Quel est le meilleur moyen de compter les lignes en utilisant PDO en PHP? Avant d’utiliser PDO, j’utilisais simplement mysql_num_rows.

fetchAll est quelque chose que je ne voudrai pas, car je peux parfois avoir affaire à de grands ensembles de données, donc ce n’est pas bon pour mon utilisation.

Avez-vous des suggestions?

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

Ce n’est pas la façon la plus élégante de le faire, et cela implique en outre une requête supplémentaire.

PDO a PDOStatement::rowCount(), ce qui apparemment fonctionne pas dans MySql. Quelle douleur.

Du Doc AOP:

Pour la plupart des bases de données, PDOStatement :: rowCount () n'a pas renvoie le nombre de lignes affectées par une instruction SELECT. Au lieu de cela, utilisez PDO :: query () pour émettre un SELECT COUNT (*) déclaration avec le même prédicats comme votre SELECT souhaité déclaration, puis utilisez PDOStatement :: fetchColumn () à récupère le nombre de lignes qui seront être retourné. Votre application peut alors effectuer l'action correcte.

EDIT: L’exemple de code ci-dessus utilise une instruction préparée, ce qui dans de nombreux cas est probablement inutile pour compter les lignes, donc:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;
236
karim79

Comme je l’ai écrit précédemment dans une réponse à une question similaire , la seule raison pour laquelle mysql_num_rows() a fonctionné est qu’elle récupérait en interne toutes les lignes pour vous donner cette information, même si cela ne vous semblait pas bien.

Donc dans PDO, vos options sont les suivantes:

  1. Utilisez la fonction FOUND_ROWS() de MySQL.
  2. Utilisez la fonction fetchAll() de PDO pour extraire toutes les lignes d'un tableau, puis utilisez count() dessus.
  3. Faites une requête supplémentaire pour SELECT COUNT(*), comme suggéré par karim79.
81
Chad Birch

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
Dan

Avant d’utiliser PDO, j’utilisais simplement mysql_num_rows().

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

mysql_num_rows(), ainsi que PDOStatement::rowCount() implique que vous avez 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 renvoyé des lignes.

Et l'ancien ne devrait jamais être utilisé. Il ne faut jamais sélectionner de lignes pour les compter, car votre serveur peut s’étouffer en raison du jeu de données volumineux renvoyé.

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

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

Si vous ne sélectionnez qu'une seule ligne, récupérez-la et vérifiez le résultat:

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

Si vous devez obtenir plusieurs lignes, vous pouvez utiliser fetchAll().

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

Notez que dans une application Web, vous ne devez jamais sélectionner une quantité énorme de lignes. Seules les lignes qui seront réellement utilisées sur une page Web doivent être sélectionnées. Dans ce but, une clause LIMIT ou similaire en SQL doit être utilisée. Et pour une quantité de données aussi modérée, il est correct d'utiliser fetchAll()

Dans un cas aussi rare où vous devez sélectionner un nombre considérable de lignes (dans une application console, par exemple), pour réduire la quantité de mémoire utilisée, vous devez utiliser une requête sans tampon, mais dans ce cas, rowCount() ne sera pas disponible de toute façon , donc cette fonction n’est pas utile non plus.

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

19

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>";
}
18
Eric Warnke

Cet article est ancien mais il est simple d'obtenir le nombre de lignes en php avec PDO

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
8
TenTen Peter

Ceci est un vieux post, mais frustré de chercher des alternatives. Il est vraiment dommage que PDO manque de cette fonctionnalité, d’autant plus que PHP et MySQL ont tendance à aller de pair. 

L'utilisation de fetchColumn () présente un défaut regrettable, car vous ne pouvez plus utiliser cet ensemble de résultats (de manière effective), car fetchColumn () déplace l'aiguille sur la ligne suivante. Ainsi, par exemple, si vous obtenez un résultat similaire à 

  1. Fruit-> Banane
  2. Fruit-> Pomme
  3. Fruits-> Orange

Si vous utilisez fetchColumn (), vous pouvez savoir qu'il y a 3 fruits renvoyés, mais si vous parcourez 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 à rechercher combien de lignes ont été retournées. Cela conduit à un codage négligé et à des résultats totalement erronés, le cas échéant. 

Alors maintenant, en utilisant fetchColumn (), vous devez implémenter un tout nouvel appel et une requête MySQL pour obtenir un nouvel ensemble de résultats de travail. (qui, espérons-le, n'a pas changé depuis votre dernière requête), je sais, peu probable, mais cela peut arriver. En outre, la surcharge des requêtes doubles sur toutes les validations du nombre de lignes. Ce qui pour cet exemple est petit, mais l'analyse de 2 millions de lignes sur une requête jointe n'est pas un prix agréable à payer. 

J'adore PHP et je soutiens chaque personne impliquée dans son développement, ainsi que la communauté dans son ensemble, en utilisant PHP quotidiennement, mais j'espère vraiment que cela sera résolu dans les prochaines versions. C'est 'vraiment' mon seul reproche avec PDO PHP, qui est par ailleurs une excellente classe.

5
Eric

Répondre à cela parce que je me suis piégé avec cela maintenant en sachant cela et peut-être que cela sera utile. 

Gardez à l'esprit que vous ne pouvez pas aller chercher les résultats deux fois. Vous devez enregistrer le résultat d'extraction dans un tableau, obtenir le nombre de lignes par count($array) et générer les résultats 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
csharp newbie

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

1
Reza Neghabi

Si vous voulez juste obtenir un nombre de lignes (pas les données) c'est à dire. en utilisant COUNT (*) dans une instruction préparée, il vous suffit 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)

Récupérer toutes les lignes (données) pour effectuer un comptage simple est un gaspillage de ressources. Si le jeu de résultats est volumineux, votre serveur peut s’étouffer.

1
madfish

Pour utiliser des variables dans la requête, vous pouvez utiliser bindValue() ou bindParam() Pour utiliser des variables dans une requête, vous devez utiliser bindValue() ou bindParam(). Et ne pas concaténer les variables avec " . $variable . "

$statement = "SELECT count(account_id) FROM account
                  WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();

GL

0
IT Developers

Quand il est question de mysql, comment compter ou obtenir combien de lignes dans une table avec PHP PDO I

// 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'];

crédits vont à Mike @ codeofaninja.com

0
Robert

Il y a une solution simple. Si vous utilisez PDO, connectez-vous à votre base de données comme suit:

try {
    $handler = new PDO('mysql:Host=localhost;dbname=name_of_your_db', 'your_login', 'your_password'); 
    $handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} 
    catch (PDOException $e) {   
    echo $e->getMessage();
}

Ensuite, la requête à la base de données sera:

$query = $handler->query("SELECT id FROM your_table WHERE ...");

Et enfin, pour compter les lignes correspondant à votre requête, écrivez comme ceci 

$amountOfRows = $query->rowcount();
0
Vlad