There are a number of ways to approach this. Here's the shortest approach.
If you use the ??
null-coalescing operator for default value, in the event that either $object
or ->keys
is undefined, then []
or an empty array will be passed for iteration, and obviously nothing happens. This is one way to avoid wrapping your foreach
loop inside a condition.
foreach($object->keys ?? [] as $key) {
// If $object or ->keys is undefined, nothing happens.
}
Now, some may object that this is unclear or unreadable; but at least it's not a ton of boilerplate, and it's very quick to add in. This approach assumes that if $object
exists and has the property keys
, then keys
will be iterable. If not, it will result in a warning on must be of type array|object.
Other than that, you'd have to wrap all your loops with a condition check, isset($object)
, or alternatively, gettype($object) === 'object'
if you want to ensure that it's an object. For some reason, is_object()
will give a warning for an undefined variable. Again, is_null()
returns true
if the variable is undefined, essentially behaving like !isset()
when negated.
As noted above, if your legacy code has objects with plural-named properties that are not iterable but also not null (e.g. ->keys = 'duck'
), you'll have to do a check on your $object->keys
with is_iterable()
before it enters the loop for an attempt at iteration.
If you pass an undefined object into is_iterable
, it's a warning again. You can, however, use the power of null-coalescing once more, where if either $object
or ->keys
is undefined, the check below reads as is_iterable(false)
(or any other non-iterable value to evaluate):
if(is_iterable($object->keys ?? false)) {
foreach($object->keys as $key) {
//...
}
}
...and that could be the sole condition that wraps your loop.
P.S. On the possible solutions in OP: A helper function results in warnings if used with an undefined variable. Also, your if( isset( $object ) && is_array( $object->keys ) )
will result in a warning if object
is defined but doesn't have the ->keys
property.