Get "PHP 8 in a Nuthshell" (Now with PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Strict typing vs. Weak typing in PHP

With PHP 5, the core team had introduced type declarations (also known as type-hinting) that allow functions to require that parameters are of a certain type at call time. If the given value is of the incorrect type, then an error is generated: in PHP 5, this will be a recoverable fatal error, while PHP 7 will throw a TypeError exception.

Type declarations can be specified by adding a type before function parameters like so.

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

So, now, whenever the method sum is called, PHP would expect to get the respective parameters of specified types. For instance, following,

var_dump(sum(3, 7)) // 10

This is fine and now you would expect that the following will throw some sort of error now that we’re using type-hinting…

var_dump(sum(3.5, 7.5)) 

But here is the catch! PHP won’t throw any error on this because by default, PHP will coerce values of the wrong type into the expected scalar type if possible. For instance, a function that is given a float for a parameter that expects an integer will get a variable of type integer. In other words, PHP will try to “fallback” to the target type from the given type whenever it can. This is called “weak typing”.

So, the previous example will print the output without any hiccup.

var_dump(sum(3.5, 7.5)) // 10
              ^    ^
              3    7

Even the string representation of these numbers will work fine. So, the following will also work.

var_dump(sum("3.5", 8)) // 11

PHP will try to coerce “3.5” to its integer value which is happen to be 3 in this case and process it further accordingly.

Strict typing

To check types strictly, PHP allow us to enable strict mode on a per-file basis. In strict mode, only a variable of the exact type of the type declaration will be accepted, or a TypeError will be thrown.

To enable strict mode, a declare statement is used with the strict_types declaration like so.

declare(strict_types=1);

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

try {
    var_dump(sum(1, 2));
    var_dump(sum("1.5", 3)); 
} catch (TypeError $e) {
    echo 'Error: '.$e->getMessage();
} 

// int(3)
// Error: Argument 1 passed to sum() must be of the type int, string given, called in [...][...] on line 11

As you can see, when giving a string value where the function is expecting an integer value, PHP will now throw a fatal error which was not possible in weak-typing.

Caveats

There is one thing to note here and that is even in strict typing, a function can be given integer when it’s expecting a float value. This is one exception in strict typing.

Apart from this, PHP doesn’t support aliases for scalar types. So, the following for example…

declare(strict_types=1);

function foo(boolean $bar) {
    return $bar;
}

try {
    var_dump(foo(true));
} catch (TypeError $e) {
    echo 'Error: '.$e->getMessage();
}

…will throw the following error,

Error: Argument 1 passed to foo() must be an instance of boolean, bool given, called in [...][...] on line 10

To fix this, we need to use bool instead of boolean when declaring the type.

declare(strict_types=1);

function foo(bool $bar) {
    return $bar;
}

try {
    var_dump(foo(true));
} catch (TypeError $e) {
    echo 'Error: '.$e->getMessage();
}

// bool(true)

And lastly, Enabling strict mode will not only affect the function type declarations but return type declarations as well.

Enabling strict mode globally?

If you want to enable strict mode globally, unfortunately, there isn’t a central configuration where you can do this. Instead, you need to add the declare(strict_types=1); statement at the top of every file you want to enable strict mode on.

So, if you want to enable strict mode globally, you can do this by using tools like sed, awk or another tool of your choice to replace all <?php with <?php declare(strict_types=1); in your project directory as mentioned by Nikita Popov in this comment.

Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, and 8.4), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?