Proposal for "Stream_Iterate"

» Metadata » Status
» Description

Overview

Here's a little class to allow accessing a traversable variable (array, Iterator, etc...) as a stream using callbacks. The variable is transversed and each key/value is passed to the callback(s) to be transformed into a string to be piped into the stream. The stream is read forward-only, and has an undetermined length.

I first developed this class to use with MDB2_Iterator and HTTP_Download (note that HTTP_Download needs the patch of bug #13125 to handle undetermined content size.)

With PHP 5.3+ there will be stream context support for copy(). That will allow to very easily dump data to file (see example)

Code Sample


<?php

require_once 'Stream/Iterate.php';

// Register class as "foreach" protocol
stream_wrapper_register('foreach', 'Stream_Iterate');

// Some data we can iterate over with foreach (array, Traversable, etc...)
// We'll assume $db MDB2 connection is configured somewhere else
$data = new MDB2_Iterate($db->query('SELECT * FROM sometable'));

// Callback to convert the data into a string that will be
// piped into the stream (any valid callback will do)
$callback = create_function('$key, $value, $iteration', 'return $key."=".implode(',', $value)."\r\n";');

// Create the context for the stream
$context = stream_context_create(array('foreach' => array('subject' => $data, 'toString' => $callback)));

$fp = fopen('foreach://subject', 'r', false, $context);

HTTP_Download::staticSend(array('resource' => $fp));

?>

URL Examples

(assuming "foreach" is the name of the registered protocol):

"key" and "value" specify which of the key and value should be passed to the callback and in which order.

  • foreach://key:value@subject
  • foreach://value:key@subject
  • foreach://key@subject
  • foreach://value@subject
  • foreach://subject

If not specified, "key:value" will be assumed. So protocol://subject
is equivalent to protocol://key:value@subject

Callback / Formatter in URL

To each of the URL examples above you can append a query string made up of. These substitute for the context options, possibly leading to more self-explanatory URLs.

  • toString=function_name
  • toString=class::method
  • formatter=class_name (class_name must implements Stream_Iterate_FormatterInterface)

Example: foreach://value@subject?toString=serialize

TODO

* Documentation / more examples (besides the test suite)

» Dependencies » Links
» Timeline » Changelog
  • First Draft: 2008-03-05
  • Proposal: 2008-03-10
  • Call for Votes: 2008-05-19
  • Voting Extended: 2008-05-27
  • Philippe Jausions
    [2008-05-01 19:23 UTC]

    I would like to call for votes on this proposal soon.

    Should stream registration handling be spun into a separate package, PHP_Stream or PHP_StreamRegistry for instance, to add convenience methods and exceptions?

  • Philippe Jausions
    [2008-05-13 21:12 UTC]

    * Updated callback API, now also passing iteration counter,
    * Added onFirst and onLast callbacks for pre and post stream content,
    * Dropped support for method calls,
    * Renamed "callback" parameter to "toString",
    * Updated regression tests,
    * Added a formatter interface,
    * Dropped the stream registration methods.
    * Added use case examples with XML output, formatter class, and GZIP.