tags:

views:

2085

answers:

3
+2  Q: 

Count with PDO

There are many conflicting statements around, what is the best way to row count using PDO in PHP with MySQL? Before using PDO I just simply used mysql_num_rows.

FetchAll is something I won't want as I may sometimes be dealing with large datasets, so not good for my use.

Any suggestions?

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

Not the most elegant way to do it, plus it involves an extra query.

PDO has PDOStatement::rowCount(), which apparently does not work in MySql. What a pain.

From the PDO Doc:

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.

EDIT: The above code example uses a prepared statement, which is in many cases is probably unnecessary for the purpose of counting rows, so:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo count($nRows);
karim79
this would mean doing an extra database query. I assume he has already done a select query and now wants to know how many rows were returned.
nickf
nickf is correct. mysql_num_rows() won't work when using PDO though will it?
James
True, apparently there's PDOStatement::rowCount() but that does not work in MySql
karim79
Yea rowCount() fails with MySQL unfortunately.
James
After a bit of googling, it's starting to look like the select count(*) might be the prettiest approach! Weird
karim79
would you really prepare that statement when it has no user inputted data? Or were you just thinking youd be called out if you used query()?
Galen
@Galen - No I wouldn't, but thanks for pointing that out. I should probably include the non-prepared-statement way of doing that. Thanks.
karim79
@Galen, answer edited to include what you pointed out.
karim79
+3  A: 

As I wrote previously in an answer to a similar question, the only reason mysql_num_rows() worked is because it was internally fetching all the rows to give you that information, even if it didn't seem like it to you.

So in PDO, your options are:

  1. Use MySQL's FOUND_ROWS() function.
  2. Use PDO's fetch_all() function to fetch all the rows into an array, then use count() on it.
  3. Do an extra query to SELECT COUNT(*), as karim79 suggested.
Chad Birch
Thank you for educating me further about mysql_num_rows() looks like that may be an important bottleneck I was giving myself. Thanks again.
James
A: 

This is an old post, but getting frustrated looking for alternatives. It is super unfortunate that PDO lacks this feature, especially as PHP and MySQL tend to go hand in hand.

There is an unfortunate flaw in using fetchColumn() as you can no longer use that result set (effectively) as the fetchColumn() moves the needle to the next row. So for example, if you have a result similar to

  1. Fruit->Banana
  2. Fruit->Apple
  3. Fruit->Orange

If you use fetchColumn() you can find out that there are 3 fruits returned, but if you now loop through the result, you only have two columns, The price of fetchColumn() is the loss of the first column of results just to find out how many rows were returned. That leads to sloppy coding, and totally error ridden results if implemented.

So now, using fetchColumn() you have to implement and entirely new call and MySQL query just to get a fresh working result set. (which hopefully hasn't changed since your last query), I know, unlikely, but it can happen. Also, the overhead of dual queries on all row count validation. Which for this example is small, but parsing 2 million rows on a joined query, not a pleasant price to pay.

I love PHP and support everyone involved in its development as well as the community at large using PHP on a daily basis, but really hope this is addressed in future releases. This is 'really' my only complaint with PHP PDO, which otherwise is a great class.

Eric