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