Hi
thank you for your RFC. I'm regretfully late to the party, but my
primary comment about the RFC relates to the latest changes.
Specifically:
Am 2026-02-27 23:21, schrieb Jakub Zelenka:
I changed it to the StreamError class constants and also move the
is*Error
functions there.
The RFC specifically defines “ranges” for the numeric value of the error
constants, some of which are quite small with only 10 values available.
I believe this is dangerous, because it is possible to run out of values
within a specific range and users might make assumptions based on the
ranges when they really should rely on the `is*()` methods to check what
type of error there is. This is not a problem that would exist if the
error code was an unbacked enum.
Contrary to Nicolas, I also don't think it is a problem for the error
code enum to be extended in future PHP versions. In other programming
languages, Rust specifically, it is also common for errors to be defined
as an enum that is explicitly defined to not be exhaustive. Here's an
example in the standard library:
https://doc.rust-lang.org/std/io/enum.ErrorKind.html. Note how the
documentation says:
In application code, use match for the ErrorKind values you are
expecting; use _ to match “all other errors”.
And the same would be possible in PHP by using a `default` branch in a
`match()` expression. We could also add a “NonExhaustiveEnum” interface
(or attribute) to PHP as a helper indicator for static analysis tools to
warn if a `default` match is missing.
--------
As for the `StreamError` class being a linked list: I agree with the
folks that mentioned that the returned errors should be an array
instead. `count()` would naturally be available, `hasCode()` can be
implemented with `array_any($errors, fn ($error) => $error->code ===
CODE_DECODING_FAILED)` and the “primary error” can be obtained with
`array_first()` (which we added in PHP 8.5).
For the naming of `stream_get_last_error()`: Within PHP we have both
`X_get_last_error()` and `X_last_error()`. The latter seems to be more
common and also what I would prefer here, because the `stream_get_`
prefix sounds to me like we would get something from a stream, but the
returned value is not related to a specific stream, but rather a global.
Best regards
Tim Düsterhus