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

Type Casting in PHP

php PHP 5.0+ 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, psalm, and php-cs-fixer — all specialist static-analysis tools. The code_pattern notes implicit coercion without strict_types=1 and unnecessary casting, which these tools flag but a default linter or compiler would not catch. Misuse is silent at runtime until edge-case inputs arrive.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is a direct substitution: swap (int) for filter_var(), add strict_types=1, or replace an implicit coercion with an explicit cast. Each fix is a single-call or single-line change with no structural impact.

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

Closest to 'localised tax' (b3). Casting choices are scoped to individual expressions or functions. While the tag 'type-system' and applies_to covering all contexts (web, cli, queue-worker) give it some breadth, the impact is localised — a wrong cast in one place rarely forces changes elsewhere across the codebase.

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

Closest to 'serious trap' (t7). The misconception field documents that (int) and intval() behave differently on objects, and common_mistakes reveal multiple non-obvious behaviours: '0' is falsy, (int)'123abc' silently truncates, (array)null vs (array)$object produce different structures, and float-to-int truncates rather than rounds. These contradict reasonable developer intuitions about type conversion, particularly coming from other languages.

About DEBT scoring →

Also Known As

PHP type casting (int) (string) settype

TL;DR

Explicitly converting a value to another type using (int), (string), (array), (object) casts or intval(), strval() functions.

Explanation

PHP supports explicit casting with (int), (bool), (float), (string), (array), (object), and (unset) (removed in PHP 8.0). Casting rules have edge cases: (int)'10abc' === 10, (bool)'' === false, (bool)'0' === false, (array)null === [], (array)'hello' === ['hello']. For integers, intval() allows a base parameter. For security-sensitive conversions, prefer intval() or settype() over casts — the intent is clearer and linting tools flag misuse more reliably. In PHP 8.0+ with strict_types, casting becomes less necessary as type errors are thrown for mismatched arguments.

Watch Out

(bool)'0' is false but (bool)'false' is true — string to bool casting only considers empty string and '0' as falsy.

Common Misconception

(int)$val and intval($val) are always identical. They produce the same result for most inputs but differ on objects — intval() on an object returns 1, while (int) on an object produces a notice in PHP 8. For arrays, both return 0 or 1 based on emptiness.

Why It Matters

PHP's casting operators (int), (float), (bool), (array) perform type coercion — understanding their edge cases prevents silent data corruption, especially with null, empty strings, and '0'.

Common Mistakes

  • (bool)'0' is false — the string '0' is the only non-empty string PHP treats as falsy.
  • (int)'123abc' returns 123 silently — use filter_var() with FILTER_VALIDATE_INT for actual validation.
  • (array)null returns [] but (array)$object returns an array of properties — different behaviours for different types.
  • Casting floats to int truncates rather than rounds — (int)4.9 is 4, not 5.

Code Examples

✗ Vulnerable
// Silent data corruption:
$val = (int)'12.5kg'; // Returns 12 — no error, 'kg' silently dropped
$flag = (bool)'0';    // Returns false — '0' is the only falsy non-empty string
$arr = (array)null;   // Returns [] — not an error

// '0' trap:
if ((bool)$_GET['active']) {} // ?active=0 evaluates to false unexpectedly
✓ Fixed
// Explicit casts — prefer over implicit coercion
\$id    = (int)    \$_GET['id'];    // '42abc' → 42, 'abc' → 0
\$price = (float)  \$_POST['price'];
\$flag  = (bool)   \$value;
\$str   = (string) \$object;        // calls __toString()
\$arr   = (array)  \$object;        // public properties as array

// intval() with base
\$oct = intval('0777', 8);  // 511
\$hex = intval('FF', 16);   // 255

// settype() — mutates the variable
settype(\$value, 'integer');

// Falsy values in PHP — know them
// false, 0, 0.0, '0', '', '0.0', [], null → all falsy
// '00', '0.0', ' ' → TRUTHY (non-empty, non-'0' strings)
var_dump((bool)'00'); // true — common surprise

Added 15 Mar 2026
Edited 22 Mar 2026
Views 66
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
ChatGPT 26 Amazonbot 7 Google 5 Perplexity 4 Unknown AI 4 Ahrefs 3 Bing 2 DuckDuckGo 1 SEMrush 1 Meta AI 1
crawler 50 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Use (int), (float), (bool), (string) for explicit conversion in contexts you control; use intval/floatval/strval for user input; never rely on implicit type coercion in strict_types code
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Implicit type coercion in arithmetic or comparison without strict_types=1; intval on already-int variable unnecessary casting
Auto-detectable: ✓ Yes phpstan psalm php-cs-fixer
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Low Context: Line
CWE-704

✓ schema.org compliant