← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

PDOStatement::rowCount()

PHP PHP 5.1+ Beginner
debt(d5/e1/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan as the tool, and the code_pattern is 'rowCount() used after SELECT statement' — this is a static analysis catch, not a compiler error or default linter, placing it squarely at d5.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is explicit: replace rowCount() with fetchAll() + count() or SELECT COUNT(*) — a direct single-call substitution at each call site.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The misuse is scoped to specific query call sites (web and cli contexts), not load-bearing across the whole architecture. Each instance is a local fix, and the broader codebase is unaffected once corrected.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field states it 'works reliably for SELECT queries' — it works on MySQL by accident, giving false confidence, but silently breaks on other drivers. This contradicts developer intuition because the method name implies it counts rows returned, not rows changed, and the MySQL-specific behavior masks the bug in the most common environment.

About DEBT scoring →

Also Known As

PDO rowCount rows affected PHP PDOStatement rowCount

TL;DR

Returns the number of rows affected by the last DELETE, INSERT, or UPDATE — unreliable for SELECT.

Explanation

rowCount() returns an integer reflecting rows modified by DML statements. For SELECT queries, the behaviour is driver-dependent — MySQL returns 0, making it unsuitable for counting result rows. Use SELECT COUNT(*) or fetchAll() + count() to count SELECT results. rowCount() is useful for detecting whether an UPDATE actually changed a row vs matched but left it unchanged.

Watch Out

rowCount() on SELECT returns 0 on most drivers even when rows exist. The PHP manual explicitly marks this behaviour as not portable.

Common Misconception

rowCount() works reliably for SELECT queries. The PHP manual explicitly warns it is not portable for SELECT — use COUNT(*) or check if fetch() returns false instead.

Why It Matters

Developers often use rowCount() to check if a SELECT returned results — this works on MySQL by accident but breaks on other databases, causing subtle portability bugs.

Common Mistakes

  • Using rowCount() to check if a SELECT found results — returns 0 on many drivers even with results.
  • Expecting rowCount() to return rows matched — it returns rows changed. UPDATE with identical values returns 0.
  • Not checking rowCount() after DELETE to confirm a row was actually removed.

Avoid When

  • Never use rowCount() to check if a SELECT returned results — use fetch() === false or count(fetchAll()) instead.

When To Use

  • Use after DELETE to verify a row was actually removed.
  • Use after UPDATE to distinguish 'row not found' from 'row found but value unchanged'.

Code Examples

✗ Vulnerable
// Wrong — rowCount() on SELECT is not portable
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
if ($stmt->rowCount() > 0) { // unreliable — may return 0 even with results
    $user = $stmt->fetch();
}
✓ Fixed
// Correct: count SELECT results
$stmt = $pdo->prepare('SELECT * FROM users WHERE active = 1');
$stmt->execute();
$users = $stmt->fetchAll();
$count = count($users); // reliable

// Correct: check rows affected by UPDATE
$stmt = $pdo->prepare('UPDATE users SET last_seen = NOW() WHERE id = ?');
$stmt->execute([$userId]);
if ($stmt->rowCount() === 0) {
    // User not found or value unchanged
}

Added 31 Mar 2026
Views 34
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Perplexity 6 Unknown AI 4 Google 3 Ahrefs 3 Meta AI 2 Claude 2 Scrapy 2 ChatGPT 1 Majestic 1
crawler 21 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Use fetchAll() + count() or SELECT COUNT(*) to count SELECT rows — use rowCount() only for INSERT/UPDATE/DELETE
📦 Applies To
PHP 5.1+ web cli
🔗 Prerequisites
PDO
🔍 Detection Hints
rowCount() used after SELECT statement
Auto-detectable: ✓ Yes phpstan
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line


✓ schema.org compliant