I would like to awaken the discussion around the RFC Nullsage Calls :
https://wiki.php.net/rfc/nullsafe_calls
Personally, I have my suspicions that PHP is starting to expose itself
to operator fatigue. There have been quite a few suggestions made over
the last couple of years that want to add new operators that would
just serve as syntax sugar for a niche problem (for example, chaining)
but serve to make things more convoluted than they need to be.
This is hardly a niche problem - The case this particular RFC deals with
is something I (and I would expect, most developers) encounter on a
regular basis.
Off the top of my head (and the RFC list for 7.4), operators added since
7.0: spaceship, null coalesce, array spread, null coalesce assign.
Assuming I totally missed a couple, that's half a dozen in 4 years. (I
would be inclined to argue for removing array spread from the list as a
consistency fix for the (argument) unpack operator).
And they're all making common code easier to read. The spaceship
operator is probably the only one I'd argue is "niche" from my personal
experience.
That said, let me now proceed to be a massive hypocrite and propose a
new operator, because IMO we should be looking to gain the most
general benefit out of the operators that are added.
Let's try and find a wider solution, for example, right now if you try
to chain things that hit a null, an Error object is thrown... so maybe
we could use that.
There's also been lots of calls for more built-in functions to throw
exceptions rather than writing notices and errors, and so the use of
try / catch would become more prominent with that as well.
But... a 5 line try/catch block can be a pain, so maybe we could
create a shorthand that would return a particular value whenever an
exception was thrown?
Instead of ...
try {
$result = $x->y()->z();
}
catch (Error $ex) {
$result = null;
}
This case isn't what the null safe calls operator deals with (as I read
the RFC and expect null safe calls to work). In the above example / the
"attempt" syntax propsal, the code catches any error (of the specified
type - eg. NullObjectError) that occurs either on the line in the try
block, or generated by any of the code in the methods in the try block
($x->y() or $x->y()->z()).
The null safe calls operator (as I would expect it to work) only deals
with either $x being null or y() returning null. If $x->y() or
$x->y()->z() internally generates an error (of any type, including the
proposed NullObjectError), I would expect that to not be caught.
As such the proposed "attempt" syntax is not something I would use or
recommend using in place of null safe calls - it would (inadvertently)
hide bugs in the code and make unexpected results harder to debug.
Only a simple assignment example is given for the "attempt" proposed
syntax. Because it uses commas and => (and the visual complexity, but
that's opinion rather than technical), the "attempt" syntax isn't usable
in many situations where null safe calls can be used.
Common use cases I can think of would be parameters in a method call,
which with null safe calls would be:
$m->n($x?->y()?->z());
Or building an array (DB record / SQL query parameter list, API
response), which with null safe calls would be:
$arr = [
'item1' => $x?->y()?->z(),
];
While other use cases outside of null safe calls certainly exist for the
proposed "attempt" syntax, I would say they're much fewer and further
between than the use cases for null safe calls and that it doesn't do
much to visually simplify those cases. And if you wanted to add anything
to either the try or catch sections, the "attempt" syntax would get very
messy (and risk introducing hard to see bugs) or require rewriting back
to a try/catch - in this regard I would say it's similar to ifs / loops
without curly braces and should be avoided.
AllenJB