declare(strict_types=1)
debt(d3/e5/b5/t7)
Closest to 'default linter catches the common case' (d3). The detection_hints list phpcs, phpstan, and php-cs-fixer — all mainstream PHP static analysis tools that can trivially flag files missing the declare(strict_types=1) header. This is a well-known sniff in phpcs and a common rule in php-cs-fixer, so the default toolchain catches it without specialist configuration.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says to add the declaration to every PHP file — but the common_mistakes warn that doing so after a large codebase exists reveals many TypeErrors, requiring fixes across many files. It's not a single-line swap for an established project; it becomes a multi-file remediation effort addressing all the coercion sites the declaration exposes.
Closest to 'persistent productivity tax' (b5). The declaration applies to web, cli, and queue-worker contexts and must be consistently maintained in every file. Missing it in any file silently reverts that file to coercive mode. This imposes an ongoing per-file discipline tax across all work streams — every new file must include it — but it doesn't reshape the architectural shape of the system, keeping it below b7.
Closest to 'serious trap' (t7). The canonical misconception is explicit: developers believe declaring strict_types=1 in one file enables strict mode application-wide, but it is strictly file-scoped. Calls from non-strict files into strict-mode functions still use coercive typing. This directly contradicts the intuition that a 'mode switch' is global, and the behavior differs from how similar language-wide pragma systems (e.g., Python's __future__ imports, Perl's use strict) work — earning t7.
Also Known As
TL;DR
Explanation
When declare(strict_types=1) is placed at the top of a PHP file, scalar type declarations (int, float, string, bool) are enforced strictly — passing the wrong type throws a TypeError rather than silently coercing the value. Without strict mode, PHP will coerce '1abc' to 1 for an int parameter, masking bugs. Strict types apply only to calls made from the file where the declaration is present, not to the function definition file. It is a best practice for all new PHP 7+ code.
Common Misconception
Why It Matters
Common Mistakes
- Not adding strict_types=1 to every file — it only applies to the file it is declared in, not the whole project.
- Expecting strict_types to affect calls into standard library functions — it only affects user-defined function calls.
- Adding strict_types after having written a lot of code and being surprised by the number of TypeErrors it reveals — adds up tech debt.
- Confusing strict_types (scalar coercion) with typed properties (class property type enforcement, always strict).
Code Examples
<?php // Without strict_types:
function double(int $n): int { return $n * 2; }
double('4'); // Returns 8 — silent coercion
double('4.5abc'); // Returns 8 — '4.5abc' coerced to 4
<?php declare(strict_types=1); // With strict_types:
double('4'); // TypeError: must be int, string given
<?php declare(strict_types=1);
// Without strict_types: PHP coerces '42' to 42 silently
// With strict_types: '42' passed to int param throws TypeError
function add(int $a, int $b): int {
return $a + $b;
}
add(1, 2); // ✓ fine
add('1', '2'); // ✗ TypeError: must be int, string given
// strict_types=1 ONLY affects calls made FROM that file
// It does not affect the callee's behaviour — it's per-file