Strict Types

Strict Types and Declared Types

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.

Strict mode rejects a numeric string (total.php)PHP
<?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";
}
Output
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.