01 · THE IDEAREAD → TRY → LEARN
Why strict types matter
A type declaration such as int $n says what a function expects. What happens when a caller passes something else depends on the typing mode. By default PHP uses coercive typing: it converts a value to the declared scalar type when it can. A string '5' passed to an int parameter quietly becomes the integer 5. That is convenient, but it can hide bugs, such as an unvalidated form value reaching code that assumed integers.
Strict mode removes the conversion. Put declare(strict_types=1); as the very first statement of a file, and scalar type declarations in that file accept only values of exactly the declared type. Anything else throws a TypeError.
The one exception is that an int is allowed where float is declared.
The call site decides
The setting belongs to the file that makes the call, not the file that defines the function. If a strict file calls a function, the arguments are checked strictly. If a file without the declaration calls the same function, the caller's coercive behavior applies and values are converted. For return values, the example below shows a strict file rejecting a mismatched return.
Two more limits to remember:
- Strict typing only covers scalar type declarations (
int,float,string,bool). - Calls made from inside internal PHP functions are not affected by
strict_types.
Worked example: strict accepts exact types
In this file, addInts() receives integers and halve() receives an integer where a float is declared. Both calls are valid in strict mode.
declare(strict_types=1);
function addInts(int $a, int $b): int
{
return $a + $b;
}
function halve(float $n): float
{
return $n / 2;
}
echo json_encode([addInts(2, 3), halve(5)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[5,2.5]
The int to float widening is the only automatic conversion strict mode performs.
Strict mode throws instead of converting
Now pass a numeric string. With the declaration present, the call fails, and we can catch the error to show that it happened.
declare(strict_types=1);
function addInts(int $a, int $b): int
{
return $a + $b;
}
try {
echo addInts('5', 3);
} catch (TypeError $e) {
echo "TypeError caught\n";
}TypeError caught
In real programs you usually do not catch this error around every call. Instead, validate or cast input at the boundary of your program, then let strict typing protect the inner code.
The same call without the declaration
Here the file has no declare. The string '5' is converted to an integer, and the float 1.0, which has no fractional part, is converted to 1.
function addInts(int $a, int $b): int
{
return $a + $b;
}
echo json_encode([addInts('5', 3), addInts(1.0, 2)], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";[8,3]
The function body is identical in the last two examples. Only the caller's mode changed the result.
Common mistakes
- Placing
declaretoo late. It must be the first statement in the file, directly after<?php. - Expecting it to protect other files. Each file opts in separately.
- Forgetting
null.nullis not accepted by a non-nullableintparameter. Use?intwhen null is valid. - Using
(int)casts to silence errors. A cast turns'abc'into0and hides the very problem strict mode is meant to reveal.
Exercise contract
Write doubleStrict(array $values): array. The starter file already enables strict types and provides a helper, doubleInt(int $n): int. For each element of $values, in order, call doubleInt() from your function. If the call succeeds, append the doubled integer to the result. If it throws a TypeError, append the string 'TypeError' instead. Return the result array.
Because the helper is called locally from a strict file, '5', true, null and 'abc' must all produce 'TypeError', while real integers, including 0 and negatives, are doubled. An empty array returns an empty array.
Recap
declare(strict_types=1);goes first in the file and affects calls made from that file.- Strict mode accepts exact scalar types, plus
intforfloat. - A mismatch throws
TypeErrorrather than converting. - Without the declaration, PHP coerces values where it can.
Functions · Arrays · Types
- Explain declare(strict_types=1) at call sites using locally called helpers
- Implement and test a deterministic PHP 8.4 function