diff options
Diffstat (limited to 'ext/spl/spl.php')
-rwxr-xr-x | ext/spl/spl.php | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/ext/spl/spl.php b/ext/spl/spl.php new file mode 100755 index 0000000000..ee92c0503c --- /dev/null +++ b/ext/spl/spl.php @@ -0,0 +1,306 @@ +<?php + +/* \brief Standard PHP Library + * + * (c) M.Boerger 2003 + */ +namespace spl { + + /*! \brief Interface to foreach() construct + * + * Any class that implements this interface can for example be used as + * the input parameter to foreach() calls which would normally be an + * array. + * + * The only thing a class has to do is + */ + interface iterator { + + /*! \brief Create a new iterator + * + * used for example in foreach() operator. + */ + function new_iterator(); + } + + /*! \brief Simple forward iterator + * + * Any class that implements this interface can be used as the + * return of a foreach interface. And hence the class itself + * can be used as a parameter to be iterated (normally an array). + * + * \code + class c implements spl::foreach, spl::forward { + private $num = 0; + function new_iterator() { + $this->num = 0; + return $this; + } + function current() { + return $this->num; + } + function next() { + $this->num++; + } + function has_more() { + return $this->num < 5; + } + } + + $t = new c(); + + foreach($t as $num) { + echo "$num\n"; + } + \endcode + * + * A very interesting usage scenario are for example database queries. + * Without this interface you need to do it without foreach or fetch the + * whole rowset into an array. + * + * In the above code the class implements both the foreach and the + * forward interface. Doing this you cannot have nested foreach calls. + * If you need this you must split the two parts. + * + * \code + class c implements spl::foreach { + public $max = 3; + function new_iterator() { + return new c_iter($this); + } + } + class c_iter implements spl::forward { + private $obj; + private $num = 0; + function __construct($obj) { + $this->obj = $obj; + } + function current() { + return $this->num; + } + function next() { + $this->num++; + } + function has_more() { + return $this->num < $this->obj->max; + } + } + + $t = new c(); + + foreach($t as $outer) { + foreach($t as $inner) { + echo "$outer,$inner\n"; + } + } + \endcode + * + * You can also use this interface with the for() construct. + * + * \code + class c implements spl::foreach { + public $max = 3; + function new_iterator() { + return new c_iter($this); + } + } + class c_iter implements spl::forward { + private $obj; + private $num = 0; + function __construct($obj) { + $this->obj = $obj; + } + function current() { + return $this->num; + } + function next() { + $this->num++; + } + function has_more() { + return $this->num < $this->obj->max; + } + } + + $t = new c(); + + for ($iter = $t->new_iterator(); $iter->has_more(); $iter->next()) { + echo $iter->current() . "\n"; + } + \endcode + */ + interface forward { + + /*! \brief Retrieve the current currentent + * + * \return \c mixed current element or \c false if no more elements + */ + function current(); + + /*! \brief Forward to next element. + */ + function next(); + + /*! \brief Check if more elements are available. + * + * \return \c bool whether or not more elements are available + */ + function has_more(); + } + + /*! \brief A restartable iterator. + * + * This iterator allows you to implement a restartable iterator. That + * means the iterator can be rewind to the first element after accessing + * any number of elements. + * + * \note If you use sequence in foreach then rewind() will be called + * first. + */ + interface sequence extends forward { + + /*! Restart the sequence by positioning it to the first element. + */ + function rewind(); + } + + /*! \brief associative interface + * + * This interface allows to implement associative iterators + * and containers. + */ + interface assoc { + + /*! \brief Retrieve the current elements key + * + * \return \c mixed current key or \c false if no more elements + */ + function key(); + } + + /*! \brief associative foreach() interface + * + * This interface extends the forward interface to support keys. + * With this interface you can do: + * \code + $t = new c(); + foreach($t as $key => $elem). + \endcode + */ + interface assoc_forward extends forward implements assoc { + } + + /*! \brief associative sequence + */ + interface assoc_sequence extends sequence implements assoc { + } + + /*! \brief array read only access for objects + */ + interface array_read { + + /*! Check whether or not the given index exists. + * The returned value is interpreted as converted to bool. + */ + function exists($index); + + /*! Read the value at position $index. + * This function is only beeing called if exists() returns true. + */ + function get($index); + } + + /*! \brief array read/write access for objects. + * + * The following example shows how to use an array_writer: + * \code + class array_emulation implemets spl::array_access { + private $ar = array(); + function exists($index) { + return array_key_exists($index, $this->ar); + } + function get($index) { + return $this->ar[$index]; + } + function set($index, $value) { + $this->ar[$index] = $value; + } + } + \endcode + */ + interface array_access extends array_read { + + /*! Set the value identified by $index to $value. + */ + function set($value, $index); + } + + /*! \brief array read/write access with customized array_writer + * + * The internal structure requires that write access via interfaces + * is divided into two parts. First the index is used to create an + * array_writer which will later receive the new value and calls the + * containers set() method with appropriate parameters. + * + * Sometimes it is helpfull to overwrite this behavior and have your + * own implementation for the array_writer. + * + * The following example shows how to use a customized array_writer: + * \code + class array_emulation_ex extends array_emulation implemets spl::array_access_ex { + private $last_index = NULL; + function new_writer($index) { + $last_index = $index; + return new array_write(&$this, $index); + } + } + \endcode + */ + interface array_access_ex extends array_access { + + /*! Create an array_writer interface for the specified index. + * + * If your container uses array_access instead of array_access_ex + * the following code would be equal to the internal new_writer() + * method: + \code + function new_writer($index) { + return new array_write(&$this, $index); + } + \endcode + */ + function new_writer($index); + } + + /*! \brief array writer interface + * + * for every write access to an array_access instance an array_writer + * is created which receives the originating object and the index as + * parameters for the constructor call. + * + * The following shows the equivalent php code for the default + * implementation array_write. + * \code + class array_write implements array_writer { + private $obj; + private $idx; + function __construct(&$obj, $index = null) { + $this->obj = $obj; + $this->idx = $index; + } + function set($value) { + return $this->obj->set($this->idx, $value); + } + } + \endcode + * + * See array_access for more. + */ + interface array_writer { + + /*! Set the corresponding value to $value. + */ + function set($value); + } + +} +?>
\ No newline at end of file |