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

intval() / Type Casting

php PHP 5.0+ Beginner
debt(d5/e3/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 and semgrep — both specialist static analysis tools — as able to catch the misuse pattern (intval() without base parameter on user input, or used for validation). This is not caught by the compiler or a default linter, but is reachable with configured specialist tooling.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix states: use intval($var, 10) with explicit base 10, or swap to filter_var with FILTER_VALIDATE_INT. This is a small, localised replacement — find all intval() calls validating input and swap the pattern — touching one call site at a time but potentially spread across multiple files, landing between e1 and e3, scored e3.

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

Closest to 'localised tax' (b3). The applies_to contexts are web, cli, and queue-worker — broad in theory — but the misuse is at individual call sites rather than an architectural choice. Each affected call site pays its own small tax; the rest of the codebase is largely unaffected. No strong gravitational pull on future design.

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

Closest to 'serious trap' (t7). The misconception field states developers believe intval() validates that a value is a valid integer, when it actually silently returns 0 for non-numeric strings like 'abc'. This directly contradicts the intuitive reading of the function name ('validate as int') and the behaviour of similar constructs in other languages or PHP's own filter_var — intval('abc') === 0 is a silent, dangerous result that contradicts developer expectations, especially when 0 may itself be a valid value (e.g. a valid ID).

About DEBT scoring →

Also Known As

intval() PHP integer cast string to int PHP

TL;DR

Casting user input to int or float is a safe way to enforce numeric types — cheaper than regex validation for IDs.

Explanation

intval($value) converts a value to integer, (int)$value does the same with less overhead. For values that must be numeric (database IDs, pagination offsets, quantities), casting is often the simplest and safest validation — non-numeric strings become 0, so you can immediately check if the result is valid. However, type casting is not a substitute for proper validation when the allowed range matters: intval("999999999999") silently overflows on 32-bit systems. Combine with range checks for critical values.

Common Misconception

intval() validates that a value is a valid integer. intval() converts any value to int — intval("abc") returns 0 silently. For validation, use ctype_digit() or filter_var($v, FILTER_VALIDATE_INT) which return false on invalid input.

Why It Matters

intval() converts a value to integer but silently returns 0 for non-numeric strings — using it for validation rather than type coercion silently accepts invalid input.

Common Mistakes

  • Using intval() to validate that input is a number — it returns 0 for 'abc', which may be a valid ID.
  • Not specifying the base parameter — intval('0x1A') returns 0 in base 10, not 26.
  • Using intval() for large numbers that exceed PHP_INT_MAX — silent truncation.
  • Using (int) cast instead of intval() for readability — they are equivalent but intval() with a base argument is more explicit.

Code Examples

✗ Vulnerable
// intval() used for validation — accepts 'abc' as 0:
$id = intval($_GET['id']);
$user = User::find($id); // find(0) might return first user or null — not an error

// Correct validation:
if (!ctype_digit($_GET['id'])) throw new InvalidArgumentException();
$id = (int) $_GET['id'];
✓ Fixed
// intval() converts to integer — stops at first non-numeric char
intval('42abc'); // 42
intval('abc');   // 0
intval('0x1A', 16); // 26 (hex with base)
intval('0777', 8);  // 511 (octal)

// For strict validation — use filter_var:
\$id = filter_var(\$_GET['id'], FILTER_VALIDATE_INT);
if (\$id === false || \$id < 1) abort(400);

// Simple cast — fastest for basic use:
\$page = max(1, (int) (\$_GET['page'] ?? 1));
\$userId = (int) \$_POST['user_id'];

Added 15 Mar 2026
Edited 22 Mar 2026
Views 27
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 2 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S
No pings yesterday
Amazonbot 9 Perplexity 3 Unknown AI 2 SEMrush 2 Majestic 1 ChatGPT 1 Google 1 Ahrefs 1
crawler 20
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Use intval($var, 10) with explicit base 10 for user input — without base parameter, strings starting with '0' are treated as octal; use filter_var with FILTER_VALIDATE_INT to reject non-integer inputs entirely
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
intval() without base parameter on user input; (int) cast on string without validation first; intval('0x1a') = 0 not 26
Auto-detectable: ✓ Yes phpstan semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Line
CWE-704

✓ schema.org compliant