I am currently reading through the PHP specification here: https://github.com/php/php-langspec
Now, I saw the list-intrinsic specification here, which states that for a list-intrinsic construct like below, the right-hand side of the simple-assignment-expression must be an expression that designates an array:
list ( list-expression-listopt ) = expression
But the documentation of list from php.net here, gives an example containing this:
$result = $pdo->query("SELECT id, name, salary FROM employees");
while (list($id, $name, $salary) = $result->fetch(PDO::FETCH_NUM)) {
//output $id, $name and $salary
}
The thing is that PDOStatement::fetch(PDO::FETCH_NUM)
returns FALSE
if there is no further row. But the right-hand side of the assignment-expression must be an array - and FALSE
is not an array. So this would result in a fatal-error, right?
Have I missed something in the specification, or is this really an inconsistency?
This is deliberately done in the implementation of php to allow this dubious piece of code:
while (list($key, $value) = each($array)) {
// ...
}
The result of each()
may be false
and would otherwise have triggered a nasty error, so while this behaviour is seemingly in violation with the specification it's mostly done to maintain backwards compatibility.
It's possible, though unlikely, that the next version of PHP will abolish this behaviour but at this point I would suggest that the specification could be edited to reflect this particular artefact, though the implied undefined behaviour could serve that purpose as well :)
The code for this can be found here; currently, the right-hand side expression supports:
ArrayAccess
,In the case of "something else" it will just assign null
to all the list variables.
Nikita Popov has proposed the following specification update as part of a pull request:
list-intrinsic must be used as the left-hand operand in a simple-assignment-expression of which the right-hand operand must be an expression that designates an array or object implementing the
ArrayAccess
interface (called the source array).
...
This intrinsic assigns one or more elements of the source array to the target variables. On success, it returns a copy of the source array. If the source array is not an array or object implementing
ArrayAccess
no assignments are performed and the return value is NULL.
(Changes emphasised)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With