php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #44392 getFilePointer() for Childs of SplFileObject
Submitted: 2008-03-10 14:45 UTC Modified: 2021-07-07 15:09 UTC
Votes:71
Avg. Score:4.2 ± 0.8
Reproduced:37 of 58 (63.8%)
Same Version:10 (27.0%)
Same OS:11 (29.7%)
From: php at benjaminschulz dot com Assigned: cmb (profile)
Status: Wont fix Package: SPL related
PHP Version: 5.3CVS-2008-03-10 (CVS) OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: php at benjaminschulz dot com
New email:
PHP Version: OS:

 

 [2008-03-10 14:45 UTC] php at benjaminschulz dot com
Description:
------------
It would be nice if it would be possible to get the underlying resource handle of an SplFileObject to be able to add stream filters on the file. Sadly the URI parser in PHP seems to be broken and URIs with filters like php://filter/read=convert.iconv.ISO-8859-15/UTF-8/resource=... cannot be used (encoding the slash doesn't work either (%2F)) therefore it would be nice if one could access the underlying resource handle f.e. by providing a protected $fp in SplFileObject one could use in a child class then and do the stream_filter_append() there.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-11-14 23:49 UTC] jordan dot raub at dataxltd dot com
add a protected member function to SplFileObject so that extending classes can have more control of the file handle... patch included against php5.2.6..


--- php-5.2.6/ext/spl/spl_directory.c   2008-02-13 04:23:26.000000000 -0800
+++ php52GetResource/ext/spl/spl_directory.c    2008-11-14 13:22:17.000000000 -0800
@@ -2218,6 +2218,15 @@
        }
 } /* }}} */

+/* {{{ proto void SplFileObject::getFileResource()
+   Seek to specified line */
+SPL_METHOD(SplFileObject, getFileResource)
+{
+       spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+       php_stream_to_zval(intern->u.file.stream, return_value);
+} /* }}} */
+
 /* {{{ Function/Class/Method definitions */
 static
 ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object___construct, 0, 0, 1)
@@ -2310,6 +2319,7 @@
        SPL_ME(SplFileObject, getMaxLineLen,  NULL, ZEND_ACC_PUBLIC)
        SPL_ME(SplFileObject, hasChildren,    NULL, ZEND_ACC_PUBLIC)
        SPL_ME(SplFileObject, getChildren,    NULL, ZEND_ACC_PUBLIC)
+       SPL_ME(SplFileObject, getFileResource,NULL, ZEND_ACC_PROTECTED)
        SPL_ME(SplFileObject, seek,           arginfo_file_object_seek,          ZEND_ACC_PUBLIC)
        /* mappings */
        SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets,      NULL, ZEND_ACC_PUBLIC)
 [2011-04-08 21:25 UTC] jani@php.net
-Package: Feature/Change Request +Package: SPL related
 [2012-11-20 23:38 UTC] mattsch at gmail dot com
What's the status of this bug?  SplFileObject is supposed to be an OO version of fopen but it's quite useless to pass into other functions like curl when those functions expect a resource.

Example:

$splFileObject = new SplFileObject('/tmp/foo', 'r');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'sftp://server.com/folder/');
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_INFILE, $splFileObject); # <-- won't work, must be file resource
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localfile));
curl_exec ($ch);
curl_close($ch);
 [2012-12-09 01:26 UTC] levim@php.net
I don't see why this method shouldn't be public. I vote for extending its 
visibility to public.
 [2012-12-12 16:12 UTC] mattsch at gmail dot com
I agree that this method should also be public.  Please implement this method ASAP.
 [2013-12-04 13:05 UTC] drgomesp at gmail dot com
Any updates on this? It would be really useful to change the visibility of this method to public.
 [2014-05-13 14:50 UTC] nyamsprod at gmail dot com
Even thought making the SplFileObject::getFilePointer() method public would be a great addition I think there is a better solution which would be to create a abstract interface "à la" Traversable but called "Streamable". 
This interface would not be implemented alone but classes that implement it like SplFileObject would be usable directly on function like stream_append_filter, streamp_get_metadata of even curl_setopt. 
That way the SplFileObject file pointer would be "usable" but its file pointer property would remain protected from a developer who would otherwise use the SplFileObject::getFilePointer() result direclty on a fclose function.
 [2015-01-14 20:28 UTC] mattsch at gmail dot com
The Streamable interface sounds like a great idea.  Now is this bug ever going to get prioritized?
 [2015-03-25 21:39 UTC] danack@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: danack
 [2017-01-22 13:30 UTC] danack@php.net
I've created a PR for this based on Jordan's patch: https://github.com/php/php-src/pull/2328
 [2017-01-22 16:10 UTC] danack@php.net
-Status: Assigned +Status: Analyzed
 [2017-01-22 16:10 UTC] danack@php.net
It might not be possible to implement this in anything close to a safe way. The code assumes that the internal file resource isn't closed by anything outside of the SplFileObject, and has no checks against whether the file resource is closed externally.

As there is no check, a segfault can occur if the file has been closed:

==13354== Process terminating with default action of signal 11 (SIGSEGV)
==13354==  Bad permissions for mapped region at address 0x0
==13354==    at 0x0: ???
==13354==    by 0x6A9DBC: _php_stream_fill_read_buffer (streams.c:675)
==13354==    by 0x6A9EE6: _php_stream_read (streams.c:722)
==13354==    by 0x606774: zim_spl_SplFileObject_fread (spl_directory.c:2932)


For the Curl use-case, you should be able to work around it, just by opening the file again directly. 

curl_setopt($ch, CURLOPT_INFILE, fopen($splFileObject->getRealPath()));
 [2017-01-22 16:11 UTC] danack@php.net
-Assigned To: danack +Assigned To:
 [2021-07-07 15:09 UTC] cmb@php.net
-Status: Analyzed +Status: Wont fix -Assigned To: +Assigned To: cmb
 [2021-07-07 15:09 UTC] cmb@php.net
This can't be implemented, since the SplFileObject internally
tracks its state (e.g. the current_line), so any change to the
exported file pointer would mess up the objects state.  While it
would be possible to export a duplicated file pointer, this
already can basically be archived in userland.

I think that something like nyamsprod's suggestion is actually
what would make sense, but that would require the RFC process[1].

[1] <https://wiki.php.net/rfc/howto>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 10:01:30 2024 UTC