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

PHP Data Types

PHP PHP 7.0+ Beginner
debt(d5/e3/b5/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 phpcs — all specialist static analysis tools that catch type misuse (missing return types, mixed coercions, loose comparisons). These are not default linters bundled with PHP itself, so the common case is not caught automatically without configuring these tools.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes adding return type declarations, switching int/bool/float usage, and enabling strict_types=1 — these are mostly local, per-file changes. Some files may need touching but it does not typically require cross-cutting architectural rework. Slightly above e1 because enabling strict_types=1 must be done per file and fixing loose comparisons or float-for-currency can require reviewing multiple call sites.

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

Closest to 'persistent productivity tax' (b5). The applies_to covers web, cli, and queue-worker contexts — the entire PHP execution model. Without strict_types and proper type declarations, every function boundary and comparison in the codebase carries latent coercion risk. This imposes an ongoing cognitive tax on maintainers across many work streams but does not fully define the system's architectural shape.

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

Closest to 'serious trap' (t7). The misconception field states developers believe PHP type declarations are optional extras, not understanding that strict_types=1 makes PHP behave like a strictly typed language at call boundaries. The common_mistakes reinforce this: '0' == false == null == 0 under loose comparison directly contradicts how most typed languages behave, and silent coercion of '42' to 42 without strict_types is a well-documented gotcha that contradicts expectations from other language ecosystems.

About DEBT scoring →

Also Known As

PHP types PHP type system PHP scalar types

TL;DR

PHP's eight primitive types — bool, int, float, string, array, object, callable, null — and how the type system coerces between them.

Explanation

PHP is dynamically typed with eight primitive types: bool, int, float (double), string, array, object, callable, and null. PHP 8.0 formalised mixed (any type) and never (no return). Type coercion rules are nuanced: '1' == 1 is true, '0' == false is true, but null == false and null == 0 are also true. PHP 8.0 changed 0 == 'foo' to false (was true in PHP 7). Typed properties (PHP 7.4+), union types (8.0), and strict_types enforce types at runtime. Understanding coercion rules is critical for security (authentication bypass via type juggling) and correctness.

Common Misconception

PHP is a loosely typed language so type declarations are optional extras. Since PHP 7, scalar type declarations and return types are enforced — and with declare(strict_types=1) PHP rejects all implicit coercions, making it behave like a strictly typed language at call boundaries.

Why It Matters

PHP has eight primitive types and loose type juggling between them — understanding how types coerce ensures predictable behaviour and prevents the class of bugs that strict_types=1 is designed to catch.

Common Mistakes

  • Not enabling strict_types=1 — PHP silently coerces '42' to 42 for int parameters without it.
  • Using == to compare values of different types — '0' == false == null == 0 in loose comparison.
  • Forgetting that array is a first-class type in PHP, not an object — json_encode behaviour differs.
  • Using float for currency — floating-point precision errors accumulate; use integer cents or bcmath.

Code Examples

✗ Vulnerable
// Loose comparison type confusion:
var_dump(0 == 'a');     // true in PHP 7, false in PHP 8 — changed!
var_dump('' == false);  // true
var_dump('0' == false); // true
var_dump(0 == null);    // true
// Use === always for predictable comparisons
✓ Fixed
// PHP 8 scalar types:
$int   = 42;          // PHP_INT_MAX = 9223372036854775807 on 64-bit
$float = 3.14;        // IEEE 754 double — avoid for money (use int cents)
$str   = 'hello';     // byte string — mb_* functions for Unicode
$bool  = true;

// Compound:
$arr   = [1, 'two', 3.0];              // ordered map
$assoc = ['key' => 'value'];
$obj   = new stdClass();
$null  = null;

// PHP 8 type system additions:
// union: int|string
// intersection: Iterator&Countable (8.1)
// never, void, mixed
// Enums with backed types (8.1)

// Type juggling changes in PHP 8:
var_dump(0 == 'foo'); // false in PHP 8 (was true in PHP 7)
var_dump(0 == '');    // false in PHP 8 (was true in PHP 7)

Added 15 Mar 2026
Edited 22 Mar 2026
Views 84
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 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 4 pings T 7 pings F 7 pings S 13 pings S 7 pings M 1 ping T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 2 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 39 Amazonbot 7 Perplexity 6 Ahrefs 4 Unknown AI 4 Google 2 Claude 2 SEMrush 2 ChatGPT 1 Bing 1 PetalBot 1 Sogou 1
crawler 68 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Use PHP's type system fully: declare return types, use int over float for counts, use bool not int for flags, and use null explicitly with nullable types
📦 Applies To
PHP 7.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Function returning 0/1 instead of bool; null or false mixed return type; missing return type declarations
Auto-detectable: ✓ Yes phpstan psalm phpcs
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Low Context: Function


✓ schema.org compliant