Scalar type declarations date from PHP 7.0 (properties from 7.4; unions in Type Declarations). By default PHP runs in coercive mode, where a declared int accepts "3" and converts it. declare(strict_types=1); as a file's first statement switches that file to strict mode: a scalar must already have the declared type, except that an int may widen to a float.
<?php
declare(strict_types=1);
function lineTotal(int $qty, float $price): float
{
return $qty * $price;
}
echo lineTotal(3, 2), "\n"; // int to float: the one widening strict mode allows
try {
echo lineTotal('3', 2.5), "\n";
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}6 lineTotal(): Argument #1 ($qty) must be of type int, string given, called in /tmp/ch04-02/total.php on line 10
Without the declare line the script prints 6 and 7.5. The mode belongs to the calling file, so a coercive file calling this lineTotal('3', 2.5) gets 7.5. Calls to built-ins obey it (strlen(12345) throws a TypeError), but a callback that a built-in invokes, such as array_map()'s closure, is still coerced. Even coercive mode rejects '8 apples' for an int since 8.0 (7.4 took it as 8). Use strict_types in every file you write.