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 <dossche.ni...@gmail.com> 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

Reply via email to