PHP strict_types declaration explained

This article explains the purpose and functionality of the declare(strict_types=1); directive in PHP. You will learn how enabling strict typing changes PHP’s default type-coercion behavior, how it enforces strict type matching for function arguments and return values, and how its file-specific scope affects your codebase.

By default, PHP operates in a coercive type mode. This means if you define a function that expects an integer, but you pass a numeric string (such as "5"), PHP will automatically convert that string into an integer and execute the function without any errors. While this dynamic behavior offers flexibility, it can lead to unexpected bugs and silent type conversions.

What strict_types=1 Does

When you place declare(strict_types=1); at the very top of a PHP file, you instruct PHP to enforce strict type checking for all function calls made within that specific file.

With strict types enabled, PHP will no longer coerce scalar types (strings, integers, floats, and booleans) to match a function’s signature. Instead, if a function expects a specific scalar type and receives a different one, PHP will immediately throw a TypeError exception.

An Example of Strict Types in Action

Consider the following function definition:

function addNumbers(int $a, int $b): int {
    return $a + $b;
}

Without strict_types=1, calling addNumbers(5, "10") works because PHP coerces the string "10" into the integer 10, returning the integer 15.

With strict_types=1 enabled at the top of the file, the exact same function call will fail:

declare(strict_types=1);

function addNumbers(int $a, int $b): int {
    return $a + $b;
}

// This throws a TypeError: Argument 2 must be of type int, string given
addNumbers(5, "10"); 

The Scope of strict_types

A critical aspect of the strict_types declaration is that it is a file-level directive. It only affects function calls made inside the file where the declaration is written.

This file-specific design ensures that third-party packages or older legacy files in your project do not break when you enable strict typing in your own files.