Le mer. 25 févr. 2026 à 20:16, Jakub Zelenka <[email protected]> a écrit :

> Hi,
>
> On Wed, Feb 25, 2026 at 7:11 PM Nicolas Grekas <
> [email protected]> wrote:
>
>> Hi Jakub,
>>
>> I would like to introduce a new stream error handling RFC that is part of
>>>> my stream evolution work (PHP Foundation project funded by Sovereign Tech
>>>> Fund) :
>>>>
>>>> https://wiki.php.net/rfc/stream_errors
>>>>
>>>>
>>> As there has not been much discussion and keeping the patch up to date
>>> is a slight pain, I plan to open voting on Friday (27/02/26) evening or
>>> Saturday (28/02/26) morning unless some changes are required ofc.
>>>
>>
>> Thanks for the reminder! I discussed this with others and we raised the
>> following points:
>>
>> 1. StreamErrorCode::None: do we need it?
>>
>> Having an enum case representing "no error" feels a bit off to me. If an
>> API needs to express the absence of an error, would,'t StreamErrorCode|null
>> be more idiomatic? StreamErrorCode::None seems like a nullable value
>> disguised as an enum case, and it means callers always have to guard
>> against it, which somewhat defeats the purpose of using an enum. Am I
>> missing a use case where ::None is genuinely needed?
>>
>
> Yeah this wouldn't make sense as enum but it would probs still make sense
> to keep it if it changes to constant
>
>
>> 2. StreamError::$next — is the naming intentional?
>>
>> Since stream_get_last_error() returns the most recent error and the chain
>> travels backwards through time, $next seems to point to the previous error
>> chronologically. Would something like $previous (echoing
>> Throwable::getPrevious()) work better, or is the current naming deliberate?
>>
>>
> I will double check it but getPrevious() might make more sense.
>
>
>> 3. Should StreamErrorCode really be an enum?
>>
>> The RFC lists in its "Future Scope" section: "Extension-specific error
>> ranges - Reserved ranges for extensions to define custom error codes."
>>
>> This gave us pause. Enums in PHP are intentionally a closed, finite type:
>> their value is precisely that "invalid states become unrepresentable." If
>> extensions can define custom error codes at runtime, the set of possible
>> values would depend on which extensions are installed, and the type would
>> no longer be truly enumerable.
>> Larry touches on this exact tension in this post: when the value space
>> needs to be open or user-extensible, an enum is the wrong tool.
>> https://www.garfieldtech.com/blog/on-the-use-of-enums#open-type
>>
>> I'd also expect the built-in list of codes to keep growing over time as
>> more wrappers and edge cases are covered; which is another hint the domain
>> may not be fixed.
>>
>> Would a set of integer constants (possibly grouped in a class or
>> interface) be appropriate? It would be more honest about the open-ended
>> nature of the value space while still allowing meaningful comparisons,
>> without creating false expectations of exhaustiveness.
>>
>
> Ok if enum should be closed, then I agree that this should be changed
> because there might be new errors. Larry suggested it before but I didn't
> see any mention that enum should stay unchanged in future versions. I will
> change it to StreamError class constants and add static helper
> classification functions there.
>
>
>>
>> 4. Using stream_context_set_default to change error_mode looks hazardous
>>
>> The RFC includes an example where stream_context_set_default is used to
>> set error_mode to StreamErrorMode::Exception globally. I'm worried about
>> the ecosystem impact here: if any library or application bootstrap does use
>> this, then existing packages using the common
>> @file_get_contents('maybe_existing_file') idiom could e.g. suddenly throw
>> uncaught exceptions, breaking behavior their authors had deliberately
>> chosen. This feels like a significant compatibility hazard for code that
>> doesn't control its full execution environment.
>>
>> Would it be worth restricting error_mode (and possibly the other new
>> options) so that they can only be set via per-call contexts, not via
>> stream_context_set_default?
>>
>>
> Hmm that's how stream context works and it would seem quite hacky to add
> restriction on global context (we would basically need to add some
> validation when global context is set). What's worse is that it would
> prevent to change error handling for cases where it is not possible to set
> context (fsockopen and various other cases). This is actually in some way
> already possible by throwing from the stream notifications (limited to http
> wrapper though) but I can see how it could have bigger impact here. I'm
> afraid the libraries will have to deal with that which should eventually
> lead to a better code.
>


Thanks for acknowledging the first items, I'm looking forward to the
update.

About this last one, I need to insist: that global behavior is going to be
a nightmare. Everytime someone proposes to add a new ini setting to
configure some global behavior, we say so. The reasons are exactly the
same. Existing code will just have to be rewritten, which might lead to
better code but also to high friction. Exactly like a BC break - it'll be
one actually.

About adding validation to stream_context_set_default, that looks like a
non issue to me.
About fsockopen et al, that's a very good reason to add a context argument.
Without that, properly using those function would mean changing the global
stat all the time. Better not plan for this.

Cheers,
Nicolas

Reply via email to