On 12/02/2023 15:46, Thomas Hruska wrote:
> On 2/12/2023 5:47 AM, Hans Henrik Bergan wrote:
>> Fwiw I would also find an $offset argument useful. fpassthru's lack of both
>> $length and $offset made my life harder when implementing "HTTP 206 Partial
>> Content" / "HTTP range requests",
>
> I was going to suggest this myself until I realized that an $offset parameter
> would be rather problematic. What happens if the offset is negative? Does a
> negative offset mean seek backwards from the current position OR start at
> that many bytes from the end of the stream? Is the offset a seek operation
> or a read operation? Not all streams are seekable and reading is generally a
> fairly slow, blocking I/O operation. Also, not all stream lengths are known.
> A negative offset in non-seekable scenarios would almost certainly have to
> throw an error. fseek()/fread() are more flexible and consistent for getting
> to the desired starting point in a source stream.
>
A negative offset would not be valid, just like it is not valid for
stream_copy_to_stream.
The offset is a seek operation just like is the case for stream_copy_to_stream.
Not all streams are seekable that's true, but the programmer using the changed
fpassthru function would have the same issue if they were to use fseek or
stream_copy_to_stream.
> A negative $length would also present some issues. Again, not all stream
> lengths are known. Correctly handling negative values would require managing
> an internally, temporarily allocated buffer of sufficient size to be able to
> backtrack streams of unknown length. And might even have to cache the entire
> stream in RAM, which would be problematic for 1GB+ streams. Or just throw an
> error for such streams. Or just restrict $length to non-negative values only.
>
> In short, a non-negative, nullable $length parameter is the only well-defined
> operation for fpassthru().
>
The behaviour of a negative $length would be the same as for
stream_copy_to_stream.
The current behaviour for negative lengths < -1 is to interpret them as
unsigned lengths.
For lengths == -1 the behaviour is to copy everything.
I don't see how this is different from for example very large lengths and an
unknown stream length.
I don't really understand your concern here. Could you please elaborate on the
problem you see?
> fpassthru() is largely a convenience wrapper around fread()/unbuffered echo
> in a loop with some extra output buffer management and is subject to PHP
> max_execution_time. For large files and/or slow/high latency networks, PHP
> can timeout before delivering all content.
>
> There are several web server extensions available (X-Sendfile and
> X-Accel-Redirect) where, for local files, the rest of the request can be
> handed off from PHP to the web server to completely avoid writing any file
> output to the output buffer and also avoid timeout issues. The existence of
> modern web server extensions for all major web servers limits the overall
> usefulness of fpassthru(). IMO, $length should be added for language-level
> completeness/convenience but it might also be a good idea to mention
> X-Sendfile/X-Accel-Redirect in the documentation for fpassthru() so that
> users are encouraged to leverage resource-efficient technologies wherever
> possible.
>
I agree it's a good idea to add this to the manual, although it should be noted
that not every place where PHP is provided for hosting has this functionality
available.
>
>> Ended up with a
>> $output = fopen('php://output', 'wb'); + stream_copy_to_stream()
>> hack because of fpassthru's shortcomings (Thanks to cmb for that hack, by
>> the way)
>>
>>
>> On Sat, Feb 11, 2023, 15:26 Niels Dossche <[email protected]> wrote:
>>
>>> Dear internals
>>>
>>> I would like to gain RFC karma for creating and proposing an RFC:
>>> "Implement GH-9673: $length argument for fpassthru".
>>> Account name: nielsdos
>>>
>>> Thanks in advance
>>> Kind regards
>>> Niels
>
>
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php