PHP PDOStatement::rowCount Tutorial
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.
Basic Definition
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.
Counting Affected Rows After UPDATE
This shows how to get the number of rows modified by an UPDATE statement.
<?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.
Counting Deleted Rows
Demonstrates using rowCount after a DELETE operation to verify deletions.
<?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.
Counting Inserted Rows
Shows how to verify the number of rows inserted with a single statement.
<?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.
SELECT Statement Behavior
Demonstrates the inconsistent behavior of rowCount with SELECT statements.
<?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.
Transactions and rowCount
Shows how rowCount works within transactions before committing changes.
<?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.
Multiple Statements
Demonstrates rowCount behavior when executing multiple statements.
<?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.
Zero Rows Affected
Shows how rowCount behaves when no rows match the operation criteria.
<?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.
Best Practices
- 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.
Source
This tutorial covered the PDOStatement::rowCount method with practical examples showing its usage in different database operation scenarios.
Author
List all PHP PDO Functions.