summaryrefslogtreecommitdiff
path: root/ext/spl/spl.php
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl/spl.php')
-rwxr-xr-xext/spl/spl.php306
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