PHP is a dynamically typed language. In addition, it performs some automatic type
conversion. Since PHP 7.0, it is possible to declare strict_types=1
, which
means that type hints are enforced. For me, this leads to unexpected behavior.
Consider the following (condensed) example.
<?php declare(strict_types=1);
$key = "42";
$value = "What's the answer?";
$store = [$key => $value];
foreach ($store as $key => $value) {
echo "Length of key '$key' is " . strlen($key) . PHP_EOL;
}
The above code will throw the TypeError strlen() expects parameter 1 to be
string, int given
. Without the declare
statement, the script runs perfectly
fine. So what’s the issue?
The error says that and integer was passed to strlen
. We have passed the key
of the array to the function. When creating the array, we set the key to "42"
.
The PHP manual on arrays says:
[…] Additionally the following key casts will occur:
- Strings containing valid decimal integers, unless the number is preceded by a + sign, will be cast to the integer type. E.g. the key “8” will actually be stored under 8. On the other hand “08” will not be cast, as it isn’t a valid decimal integer.
- […]
This means, our string key "42"
was automatically converted to the integer 42.
In this contrived example, it’s easy to fix, but I can imagine countless
examples where user input is used as array keys, which then, in turn, might lead
to type errors. A prime example is $_GET
.
This might also interest you