In PHP's database abstraction layer PDO (PHP Data Objects), PDOStatement::rowCount() is a common method that returns the number of rows affected by the last SQL execution. However, many developers will find that the method behavior is inconsistent when using it in different database drivers, and even fail to get the expected results in some scenarios.
According to the instructions of the official PHP documentation :
For most databases, rowCount() is only applicable to DELETE , INSERT , or UPDATE statements. For SELECT statements, some database drivers may return the number of rows affected, but this is not part of the unified PDO behavior.
That is, the behavior of rowCount() depends on the underlying database driver implementation.
Database Type | Support rowCount for SELECT statements | Support rowCount for UPDATE/DELETE/INSERT |
---|---|---|
MySQL | ? Unreliable (usually return 0) | ? Return the number of affected rows |
PostgreSQL | ? support | ? support |
SQLite | ? support | ? support |
MSSQL | ? (Dependency driver implementation) | ? |
For example, in MySQL:
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->query("SELECT * FROM users");
echo $stmt->rowCount(); // Usually return 0
But in PostgreSQL or SQLite, the actual number of rows may be returned.
The main reason is that the database driver executes SQL in different ways, especially for SELECT . Some drivers do not load all results in advance, but instead fetch data while traversing. In this case, it cannot know how many rows there are in advance.
The official MySQL driver ( mysqlnd ) clearly states that for SELECT , rowCount() should not be dependent.
$stmt = $pdo->query("SELECT * FROM users");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$count = count($rows);
echo "common {$count} Line data";
or:
$count = 0;
$stmt = $pdo->query("SELECT * FROM users");
while ($row = $stmt->fetch()) {
$count++;
}
echo "common {$count} Line data";
Note: If the data volume is large, fetchAll() will occupy a lot of memory, and it is recommended to use loop counting.
$stmt = $pdo->prepare("UPDATE users SET status = 'active' WHERE last_login > NOW() - INTERVAL 7 DAY");
$stmt->execute();
echo "Updated " . $stmt->rowCount() . " OK";
rowCount() for such operations is usually reliable.
You can encapsulate your own rowCount function, judge the SQL type and select the appropriate statistical method:
function safeRowCount(PDOStatement $stmt, $sqlType = 'SELECT') {
if (strtoupper($sqlType) === 'SELECT') {
return count($stmt->fetchAll());
} else {
return $stmt->rowCount();
}
}
This allows you to keep your behavior consistent in different database drivers.
The inconsistent behavior of PDOStatement::rowCount() is one of the common pitfalls in PHP database development. Understanding its underlying mechanism and selecting the appropriate processing method based on SQL types is the key to writing highly compatible code.
For more sample code or sharing experience, please visit our technology community: https://gitbox.net/forum .