Hello internals!
There is a lot of code in existence that does something like this:
$item['id'] ? [$item['id']] : $something_else
which to dissolve the current warning must be changed to something like
this:
!empty($item['id']) ? [$item['id']] : $something_else
However, if performance is an issue, we can do this in one less opcode (in
fact, the same number of opcodes as the original):
empty($item['id']) ? $something_ else : [$item['id']]
As far as I can tell, when single array access is the only test in a
ternary operation, it is exactly the same semantics as wrapping the array
access in a "!empty()". Fixing this warning seems like a lot of "busy work"
with little to no tangible benefit.
I'd like to propose and implement an RFC that would consider dropping the
warning if and only if array access is the only test in ternary and short
ternary (?:) operations but first I'd like to start a discussion to see if
it is worth pursuing. I'd like to target PHP 8.2 or 8.3.
It may also be worth discussing extending it to multiple array accesses
because to invert the not empties is counter-intuitive and error-prone:
!empty($a['test']) && !empty($a['ok']) ? 'a' : 'b';
becomes:
empty($a['test']) || empty($a['ok']) ? 'b' : 'a';
which was before (and IMHO, more readable):
$a['test'] && $a['ok'] ? 'a' : 'b';
This is very tricky to get right and to be fair, there will probably be
automated tools (if you trust such things on large codebases). There are
also performance issues to consider, as some basic benchmarks show
ISSET_ISEMPTY_DIM_OBJ is 6x slower than FETCH_DIM_R.
Robert Landers
Software Engineer
Utrecht NL
I'd like to propose and implement an RFC that would consider dropping the
warning if and only if array access is the only test in ternary and short
ternary (?:) operations but first I'd like to start a discussion to see if
it is worth pursuing. I'd like to target PHP 8.2 or 8.3.
The warning comes from the array key being missing, not from being
empty. There are many values which are empty which do not emit the warning.
If you want to provide a default should the array key be missing you
want null coalesce.
$x = $array['foo'] ?? 'somethingelse';