With strict types enabled, array_map converts types anyways

656 views Asked by At

I've came across a really interesting bug in PHP 7.0.11 where declare(strict_types=1); enabled does not make the array_map() nor array_walk() aware of strict types. I read somewhere that by enabling strict types PHP also uses strict types in core functions, but this is not the case. Look at this example code, it should throw TypeError exception:

declare(strict_types=1);

$myArray = [12, 'string value', 'another string value', 5];

array_map('validateMyArrayValues', $myArray);

function validateMyArrayValues(string $item)
{
    var_dump($item);
}

The var_dump result is:

test.php:13:
    string(2) "12"
test.php:13:
    string(12) "string value"
test.php:13:
    string(20) "another string value"
test.php:13:
    string(1) "5"

All the integer values are typecasted into strings which is obviously an issue. This raises the question should I drop declare(strict_types=1); altogether and use is_* functions and throwing exceptions?

1

There are 1 answers

2
Machavity On BEST ANSWER

It's not a bug (hat tip to Room 11 for pointing me in the right direction)

Here's the Strict Types RFC. It's really, really long and the most contentious RFC in the history of PHP (and I'm being serious). Here's the relevant portions cut out for you

This proposal builds in weak type checking by default (using the same rules), for internal and user functions.

A significant portion of the PHP community appears to favor fully-strict types. However, adding strictly type-checked scalar type declarations would cause a few problems:

Existing code which (perhaps unintentionally) took advantage of PHP's weak typing would break if functions it calls added scalar type declarations to parameters. This would complicate the addition of scalar type declarations to the parameters of functions in existing codebases, particularly libraries.

So this isn't a bug. This was part of the grand compromise that made this possible (baby steps towards stricter typing, if you will). Functions ignore strict typing. Yes, it's inconsistent with other languages (a fact the RFC notes in detail), but that's how the PHP community decided it should be for now.