Discover the PHP PDOStatement::rowCount method to count rows affected by SQL queries.
last modified April 19, 2025
The PDOStatement::rowCount method returns the number of rows affected by the last SQL statement. It’s useful for checking the impact of operations.
PDOStatement::rowCount returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement. For SELECT statements, behavior varies.
Syntax: public PDOStatement::rowCount(): int. Returns the number of rows as an integer. Not all databases support row counts for SELECT.
This shows how to get the number of rows modified by an UPDATE statement.
pdo_rowcount_update.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('UPDATE users SET active = 1 WHERE last_login > ?');
$stmt->execute([strtotime('-30 days')]);
$count = $stmt->rowCount();
echo "Updated $count user records";
} catch (PDOException $e) { echo “Error: " . $e->getMessage(); }
This updates user records and shows how many were modified. The rowCount method returns the number of rows changed by the UPDATE operation.
Demonstrates using rowCount after a DELETE operation to verify deletions.
pdo_rowcount_delete.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('DELETE FROM temp_sessions WHERE expires < ?');
$stmt->execute([time()]);
$deleted = $stmt->rowCount();
echo "Deleted $deleted expired sessions";
} catch (PDOException $e) { echo “Error: " . $e->getMessage(); }
This deletes expired sessions and reports how many were removed. rowCount accurately reflects the number of deleted rows in this case.
Shows how to verify the number of rows inserted with a single statement.
pdo_rowcount_insert.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('INSERT INTO log_entries (message) VALUES (?), (?), (?)');
$stmt->execute(['Startup', 'Initialization', 'Ready']);
$inserted = $stmt->rowCount();
echo "Inserted $inserted log entries";
} catch (PDOException $e) { echo “Error: " . $e->getMessage(); }
This inserts multiple rows with one statement. rowCount returns the total number of rows inserted, which is 3 in this example.
Demonstrates the inconsistent behavior of rowCount with SELECT statements.
pdo_rowcount_select.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT * FROM products WHERE stock > 0');
$rows = $stmt->fetchAll();
echo "Fetched " . count($rows) . " products\n";
echo "rowCount reports: " . $stmt->rowCount() . " products";
} catch (PDOException $e) { echo “Error: " . $e->getMessage(); }
With MySQL, rowCount may not return the SELECT result count. Always use fetchAll or similar methods to count SELECT results reliably.
Shows how rowCount works within transactions before committing changes.
pdo_rowcount_transaction.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->beginTransaction();
$stmt = $pdo->prepare('UPDATE accounts SET balance = balance - ? WHERE user_id = ?');
$stmt->execute([100, 1]);
$affected = $stmt->rowCount();
echo "Temporarily affected $affected rows (not committed yet)";
$pdo->commit();
} catch (PDOException $e) { $pdo->rollBack(); echo “Error: " . $e->getMessage(); }
rowCount reports affected rows immediately, even in transactions. The count reflects changes that would occur if committed, but aren’t permanent yet.
Demonstrates rowCount behavior when executing multiple statements.
pdo_rowcount_multiple.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt1 = $pdo->prepare('UPDATE products SET views = views + 1 WHERE id = ?');
$stmt1->execute([5]);
echo "Updated " . $stmt1->rowCount() . " product\n";
$stmt2 = $pdo->prepare('DELETE FROM cart_items WHERE session_id = ?');
$stmt2->execute(['old_session']);
echo "Deleted " . $stmt2->rowCount() . " cart items";
} catch (PDOException $e) { echo “Error: " . $e->getMessage(); }
Each statement maintains its own row count. The counts are specific to each PDOStatement object and don’t interfere with each other.
Shows how rowCount behaves when no rows match the operation criteria.
pdo_rowcount_zero.php
<?php
declare(strict_types=1);
try { $pdo = new PDO(‘mysql:host=localhost;dbname=testdb’, ‘user’, ‘password’); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('UPDATE users SET status = ? WHERE user_id = ?');
$stmt->execute(['inactive', 9999]);
if ($stmt->rowCount() === 0) {
echo "No user with ID 9999 exists";
} else {
echo "Updated user status";
}
} catch (PDOException $e) { echo “Error: " . $e->getMessage(); }
When no rows match the operation criteria, rowCount returns 0. This can be used to detect when operations don’t affect any database rows.
Use for DML: Best with INSERT, UPDATE, DELETE.
SELECT caution: Behavior varies by database driver.
Error checking: Verify operations affected expected rows.
Transactions: Counts reflect uncommitted changes.
Performance: No significant overhead for rowCount.
This tutorial covered the PDOStatement::rowCount method with practical examples showing its usage in different database operation scenarios.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all PHP PDO Functions.