Row count with PDO

前端 未结 23 3153
春和景丽
春和景丽 2020-11-21 22:57

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

23条回答
  •  北海茫月
    2020-11-21 23:35

    As it often happens, this question is confusing as hell. People are coming here having two different tasks in mind:

    1. They need to know how many rows in the table
    2. They need to know whether a query returned any rows

    That's two absolutely different tasks that have nothing in common and cannot be solved by the same function. Ironically, for neither of them the actual PDOStatement::rowCount() function has to be used.

    Let's see why

    Counting rows in the table

    Before using PDO I just simply used mysql_num_rows().

    Means you already did it wrong. Using mysql_num_rows() or rowCount() to count the number of rows in the table is a real disaster in terms of consuming the server resources. A database has to read all the rows from the disk, consume the memory on the database server, then send all this heap of data to PHP, consuming PHP process' memory as well, burdening your server with absolute no reason.
    Besides, selecting rows only to count them simply makes no sense. A count(*) query has to be run instead. The database will count the records out of the index, without reading the actual rows and then only one row returned.

    For this purpose the code suggested in the accepted answer is fair, save for the fact it won't be an "extra" query but the only query to run.

    Counting the number rows returned.

    The second use case is not as disastrous as rather pointless: in case you need to know whether your query returned any data, you always have the data itself!

    Say, if you are selecting only one row. All right, you can use the fetched row as a flag:

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

    In case you need to get many rows, then you can use fetchAll().

    fetchAll() is something I won't want as I may sometimes be dealing with large datasets

    Yes of course, for the first use case it would be twice as bad. But as we learned already, just don't select the rows only to count them, neither with rowCount() nor fetchAll().

    But in case you are going to actually use the rows selected, there is nothing wrong in using fetchAll(). Remember that in a web application you should never select a huge amount of rows. Only rows that will be actually used on a web page should be selected, hence you've got to use LIMIT, WHERE or a similar clause in your SQL. And for such a moderate amount of data it's all right to use fetchAll(). And again, just use this function's result in the condition:

    $stmt->execute();
    $data = $stmt->fetchAll();
    if (!$data) { // again, no rowCount() is needed!
        echo 'No data found';
    }
    

    And of course it will be absolute madness to run an extra query only to tell whether your other query returned any rows, as it suggested in the two top answers.

    Counting the number of rows in a large resultset

    In such a rare case when you need to select a real huge amount of rows (in a console application for example), you have to use an unbuffered query, in order to reduce the amount of memory used. But this is the actual case when rowCount() won't be available, thus there is no use for this function as well.

    Hence, that's the only use case when you may possibly need to run an extra query, in case you'd need to know a close estimate for the number of rows selected.

提交回复
热议问题