Making stream functions accepting SplFileObject as valid parameter

php.internals

nyamsprod the funky webmaster

8 years ago
Hi internals, I've been following the resolution of this bug: https://bugs.php.net/bug.php?id=44392 and it seems that there is no safe way to expose the internal `SplFileObject` filepointer. So I was wondering if we could not do things differently and instead of trying to expose the internal file pointer make any `stream_*` function which accept a resource stream as parameter accept a `SplFileObject`. By doing so we could resolve a couple of issues I encountered while using this SPL object without adding any new method to the class we could: - get informations about the object seekable and open mode status using `stream_get_meta_data`. - append/prepend stream filters without using the `php://filter/` hack which has its own limitations. What do you think ?

Dan Ackroyd

8 years ago
On 29 September 2017 at 07:46, nyamsprod the funky webmaster <nyamsprod@gmail.com> wrote:
> Hi internals, > > I've been following the resolution of this bug: > > https://bugs.php.net/bug.php?id=44392 > > and it seems that there is no safe way to expose the internal > `SplFileObject` filepointer.
Hi nyamsprod the funky webmaster, It seems that people are scared to comment on a streams related question... I'm not sure that making stream_* functions accept SplFileObject's would be an appropriate way to solve this problem; it's just too much of a hack. However, although it's not safe to expose the underlying file handle used by SplFileObject, I think it _might_ be safe to allow the SplFileObject to return a stream that represents the file, but with the necessary php_stream_ops that aren't safe to use replaced with NOP operations, similar to how it is done in the pgsql extension: https://github.com/php/php-src/blob/879126a2cedef5b6e1c1f701ade17ca3da9a39ec/ext/pgsql/pgsql.c#L5406-L5409 static int php_pgsql_fd_close(php_stream *stream, int close_handle) /* {{{ */ { return EOF; } To expose the internal stream to userland. I'd really like to hear from anyone who knows about streams internals to know if that's a viable approach. cheers Dan Ack

Sara Golemon

8 years ago
On Tue, Oct 3, 2017 at 9:44 AM, Dan Ackroyd <danack@basereality.com> wrote:
> On 29 September 2017 at 07:46, nyamsprod the funky webmaster > <nyamsprod@gmail.com> wrote: >> >> I've been following the resolution of this bug: >> >> https://bugs.php.net/bug.php?id=44392 >> >> and it seems that there is no safe way to expose the internal >> `SplFileObject` filepointer. > > > It seems that people are scared to comment on a streams related question... >
Nah, just distr... OOH SHINY!
> I'm not sure that making stream_* functions accept SplFileObject's > would be an appropriate way to solve this problem; it's just too much > of a hack. >
Implementation wise, about as difficult as you'd imagine. We have php_stream_from_zval() which is a central place which could be made smarter, though most (all?) stream related functions have IS_RESOURCE checks that'd have to be dealt with, so it still means touching the world.
> However, although it's not safe to expose the underlying file handle > used by SplFileObject, I think it _might_ be safe to allow the > SplFileObject to return a stream that represents the file, but with > the necessary php_stream_ops that aren't safe to use replaced with NOP > operations, similar to how it is done in the pgsql extension: > https://github.com/php/php-src/blob/879126a2cedef5b6e1c1f701ade17ca3da9a39ec/ext/pgsql/pgsql.c#L5406-L5409 >
I like this approach in the abstract (though I haven't paged in the entire problem space yet). A proxy wrapper provides (possibily implemeted on the SplFileObject itself) keeps the scope of the change localized to SPL and has little residual hack smell. -Sara

nyamsprod the funky webmaster

8 years ago
Does adding new methods to SplFileObject easier ? It would mean adding a getMetaData() (to return stream_get_meta_data infos) method and (append/prepend/remove)Filter methods to add stream filters API. On Tue, Oct 3, 2017 at 5:21 PM, Sara Golemon <pollita@php.net> wrote:

Sara Golemon

8 years ago
On Thu, Oct 5, 2017 at 6:42 AM, ignace nyamagana butera <nyamsprod@gmail.com> wrote:
> Does adding new methods to SplFileObject easier ? It would mean adding a > getMetaData() (to return stream_get_meta_data infos) method and > (append/prepend/remove)Filter methods to add stream filters API. >
That's still a hack, and a piecemeal one at that. Danack's approach of creating a proxy stream really is more comprehensive and correct. -Sara