Re: [RFC] Nullable and non-nullable cast operators
| From: | Alexandre Daubois | Date: | Mon, 27 Oct 2025 08:03:06 +0000 |
| Subject: | Re: [RFC] Nullable and non-nullable cast operators | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-128973@lists.php.net to get a copy of this message | ||
Hi Rowan,
> PHP definitely needs a better range of cast operators, and I've been thinking for a while
> about what that should look like. My main concern with this proposal is that it picks a few specific
> options and uses syntax in a way that's not easy to extend.
Thank you for your interest! I get your concerns about the extension
of such syntax, but we don't feel that there would be a particular
need of extending this syntax. The syntax does not bring something
really new: the behavior described in the RFC already exists in PHP —
we are just making it available at the cast level with explicit null
handling.
> What I mean by that is that there are, roughly, three things that a user might want to specify:
>
> 1) What *output types* are desired?
> 2) What *input values* are considered castable?
> 3) What should happen for *invalid* values?
>
> For (1), our current casts allow base scalar types + array. I can definitely see value in
> allowing nullable types there, but also other complex types, e.g. (string|Widget)$foo could be
> equivalent to $foo instanceof Widget ? $foo : (string)$foo
>
> For (2) and (3), you could say our current casts accept anything, but you could argue that they
> replace invalid values with a fixed "empty" value from the target type.
>
> More importantly, there are a few different things you might *want* to happen:
>
> - throw an exception, because you expect the cast to succeed, and want to abort if it
> doesn't
> - fill with null, or with some default value from the target type, e.g. because you're
> *sanitising* untrusted data and want to proceed with the best you can get
> - detect that it *would* fail, e.g. because you're *validating* data.
>
> Throwing exceptions is generally a poor choice for validation or sanitisation, because you have
> to either make the user fix one mistake at a time, or add a separate try-catch around every check.
>
> The current RFC adds support for nullable types (1), but only if you *also* want a different
> set of validation rules (2) *and* a different behaviour if those rules aren't met (3).
> That's a *useful* combination, but it's not the *only* useful combination. Using the
> (?type) syntax for that combination makes it hard to add other combinations in future.
I'm sorry, I think I don't get what you mean. It looks really complex
for something that we would like to keep straightforward. This RFC
doesn't really introduce *new * behavior: these rules already exist in
the engine. Casting with these new operators is indeed stricter than
existing ones and it _may_ look it introduces brand new rules, but it
actually isn't. This strictness comes from implicit casts already done
at function calls.
— Alexandre Daubois