Php User Streams - why doesn't anyone use them?

Php user streams are amazing - they're powerful, fun, and make things like a templating system with filters and multiple back ends quick and easy.

Here's a little "test script" that shows you how to implement contexts for your streams. What are contexts? They're resources that hold additional information. Built in php streams, such as the ftp streams, already have contexts you can set. But they're also great to use in your own user land streams.

class test
* public function stream_open
* This method is called immediately after your stream object is created.
* You can use parse_url() to break path apart.
* You are responsible for checking that mode is valid for the path requested.
* STREAM_USE_PATH: use the include_path
* STREAM_REPORT_ERRORS: trigger_error() during opening of the stream
* If the path is opened successfully, and STREAM_USE_PATH is set in options, you should set opened_path to the full path of the file/resource that was actually opened.
* @param string $path url passed to fopen()
* @param string $mode see fopen docs for mode choices
* @param int $options STREAM_USE_PATH and STREAM_REPORT_ERRORS optionally orred together
* @param string $opened_path path actually opened
* @return type bool
public function stream_open($path, $mode, $options, $opened_path)
// bug fix for include
if (!isset($this->context)) { $this->context = stream_context_get_default(); }
$context = stream_context_get_options($this->context);
return true;

* public function stream_close
* called on fclose() - release resources
* @return void
public function stream_close()

* public function stream_read
* fread() and fgets() - return up-to count bytes of data from the current
* read/write position as a string. If no more data is available, return
* either FALSE or an empty string. Update the read/write position of the
* stream by the number of bytes that were successfully read.
* @param int $count
* @return type about
public function stream_read($count)

* public function stream_eof
* used for feof() return TRUE if the read/write position is at the end of
* the stream and if no more data is available to be read
* @return bool
public function stream_eof()

* public function stream_stat
* fstat() - returns array(dev, ino, mode, nlink, uid, gid, size, atime,
* mtime, ctime) and may have additional items
* @return array
public function stream_stat()

stream_wrapper_register('test', 'test');
$default = stream_context_get_default(array('test'=> array('type' => 'pgsql')));

$different = stream_context_get_default(array('test'=> array('param' => 'value')));
stream_context_set_option($different, 'test', 'param', 'new_value');
file_get_contents('test://test', false, $different);

stream_context_set_option($different, 'test', 'param', 'another_value');

$new = stream_context_create(array('test'=> array('param' => 'secondvalue')));
file_get_contents('test://test', false, $new);


Notice the little "bug fix" there. Right now include is slightly broken, because $this->context isn't getting populated (I'm hunting through the source to fix it...if I don't get it done by |tek I'll bug Sara ;)

Now you know how to pass information into your stream wrapper!


Chris Hartjes

I keep forgetting about streams (PHP 4 in the brain I guess), but can you point to an example of doing templates using streams? It seemed such a teaser to not provide an example. :)

2007-05-07 4:34 am

Philip Olson

Also if you or anyone else would like to help document streams... :) start here:rnrn

2007-05-07 11:14 am


i think i have a fix for the bug!rnrn if (!isset($this->context)) { $this->context = stream_context_get_default(); }rnrnneeds to bernrn if (!$this->context) { $this->context = stream_context_get_default(); }rnrnhope that helps

2007-05-08 12:06 pm


Chris: hopefully I'll have time next month to do a long post on it ;)

Philip: if you had a nice web interface for writing docbook and sending the patch to php.doc I'd go for it, but docbook sucks

Jordan: um you're totally missing the point - the bug is that $this->context is not set when you do an include with a user stream wrapper - the bug fix IS that line, it populates the stream wrapper context when the engine doesn't do it right

2007-05-08 5:07 pm


I have built a new application named freeFAX (see community site). This application uses CURL function to login and get some information from an Internet Provider. When reading from the external site, gtk application is locked. So I would be very interested in a more gtk-friendly library for doing GET and POST to an external site.rnrnI'm also interested because I have some blinking led indicating network activity. Those leds can't really blink :-(rnrnif you have any idea :-)rnrnPS: yes I know, CURL has some callback features.rn

2007-05-17 8:05 am

Philip Olson

Regarding a web interface to create php doc patches... we're working on it! Also, DocBook as a whole may feel overwhelming but our use of its syntax is already defined. Typically all people do is copy a similar file, change a few names, and then alter the text. Or simply insert text into the file. DocBook is fun! :)

2007-05-22 11:29 am

Pixelated Dreams

[...] streams are absolutely amazing. As mentioned by Elizabeth Smith (a great read if you don't know how to use streams) PHP streams are super powerful. Streams is [...]

2007-09-11 7:45 pm

PHP Streams Rock my World! « Resistance is futile

[...] Streams Rock my World! Por: Davey ShafikPHP streams are absolutely amazing. As mentioned by Elizabeth Smith (a great read if you don’t know how to use streams) PHP streams are super powerful. Streams [...]

2007-09-12 10:31 am

Cesar D. Rodas » Blog Archive » PHP: Amazon S3 Stream Wrapper

[...] that is with the possibility to register new Stream Wrapper. (see this articles are good, this, an this too).Usually IO functions (fopen, unlink, mkdir and others) are handle by the Operating System or an [...]

2007-09-24 2:21 pm

Post a Reply