Edit report at https://bugs.php.net/bug.php?id=65581&edit=1

 ID:                 65581
 Updated by:         jpa...@php.net
 Reported by:        ivan dot enderlin at hoa-project dot net
 Summary:            stream_get_contents does not seek with a stream
                     wrapper
-Status:             Open
+Status:             Closed
 Type:               Bug
 Package:            *General Issues
 PHP Version:        master-Git-2013-08-29 (Git)
-Assigned To:        
+Assigned To:        jpauli
 Block user comment: N
 Private report:     N

 New Comment:

Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is because your stream_seek() function does not return the right value.
stream_seek() should return TRUE if the seek has successed, you return the 
value 
of fseek(), which is 0 on success.

Additionally, you have to implement stream_tell() so that the underlying layer 
can ask for it and know where the stream position is.
stream_tell() is called just after stream_seek() has successed, thus it is 
needed, even if you never call ftell() on your own stream, the underlying layer 
does.

Correct code is :

<?php

class StreamWrapper {

    protected $_stream = null;

    public function stream_open ( $path, $mode, $options, &$openedPath ) {

        $this->_stream = fopen(__FILE__, $mode);

        return true;
    }

    public function stream_seek ( $offset, $whence = SEEK_SET ) {

        var_dump('seek to ' . $offset);

        if (fseek($this->_stream, $offset, $whence) == 0) {
            return true;
        }
        return false;
    }

    public function stream_tell()
    {
        return ftell($this->_stream);
    }

    public function stream_read ( $count ) {

        return fread($this->_stream, $count);
    }

    public function stream_stat ( ) {

        return fstat($this->_stream);
    }

    public function stream_eof ( ) {

        return feof($this->_stream);
    }
}

stream_wrapper_register('foo', 'StreamWrapper');

$a = fopen('foo://bar', 'rb');
var_dump(stream_get_contents($a, 30, 4));


Previous Comments:
------------------------------------------------------------------------
[2013-08-29 08:40:49] ivan dot enderlin at hoa-project dot net

Oh also the bug disappears with:

    fseek($a, 4);
    stream_get_contents($a, 30);

------------------------------------------------------------------------
[2013-08-29 08:28:08] ivan dot enderlin at hoa-project dot net

Description:
------------
When calling stream_get_contents() with $offset >= ftell() *through a stream 
wrapper*, the internal pointer of the stream is moved but stream_get_contents() 
throws an error: "Failed to seek to position $offset in the stream".

While monitoring the source code (ext/standard/streamsfuncs.c, at line 404, no 
kidding ;-)), it appears that it is a normal behaviour since seek_res is set to 
-1 at line 426 (with the code bellow). I did not understand why (I looked at 
php_stream_seek implementation but I was not able to understand).

Change fopen('foo://bar', 'rb') for fopen(__FILE__, 'rb') and the issue 
disappears. That's why I think it is related to stream wrapper, but I cannot 
ensure that.

Test script:
---------------
<?php

class StreamWrapper {

    protected $_stream = null;

    public function stream_open ( $path, $mode, $options, &$openedPath ) {

        $this->_stream = fopen(__FILE__, $mode);

        return true;
    }

    public function stream_seek ( $offset, $whence = SEEK_SET ) {

        var_dump('seek to ' . $offset);

        return fseek($this->_stream, $offset, $whence);
    }

    public function stream_read ( $count ) {

        return fread($this->_stream, $count);
    }

    public function stream_stat ( ) {

        return fstat($this->_stream);
    }

    public function stream_eof ( ) {

        return feof($this->_stream);
    }
}

stream_wrapper_register('foo', 'StreamWrapper');

$a = fopen('foo://bar', 'rb');
var_dump(stream_get_contents($a, 30, 4));


Expected result:
----------------
no error

Actual result:
--------------
error


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=65581&edit=1

Reply via email to