helly Thu Dec 4 14:39:47 2003 EDT Added files: /spl/examples autoload.inc
Modified files: /spl README spl.php /spl/examples dba_array.php dba_dump.php directorytree.php findfile.php ini_groups.php tree.php Log: Update documentation
Index: spl/README diff -u spl/README:1.3 spl/README:1.4 --- spl/README:1.3 Mon Jun 23 18:37:12 2003 +++ spl/README Thu Dec 4 14:39:46 2003 @@ -1,88 +1,26 @@ This is an extension that aims to implement some efficient data access interfaces and classes. You'll find the classes documented using php -code in the file spl.php. +code in the file spl.php or in the corresponding .inc file in the examples +subdirectory. Based on the internal implementations or the files in the +examples subdirectory there are also some .php files to experiment with. + +The .inc files are not included automatically because the are sooner or +later intergrated into the extension. That means that you either need to +put the code of examples/autoload into your autoprepend file or that you +have to point your ini setting auto_prepend_file to this file. -There are special SPL interfaces that provides the ability to hook into -foreach and array reading/writng. By inheriting these interfaces, instances -of the resulting classes can be iterated using the foreach construct or -use array read write notation. +1) Iterators -Look into the examples subdirectory for some basic examples which will -demonstracte this. +SPL offers some advanced iterator algorythmns: -Also some classes of extensions like SQLite inherit SPL interfaces so that -they take advantage of the foreach or array overloading. +interface RecursiveIterator implements Iterator +class RecursiveIteratorIterator implements Iterator +abstract class FilterIterator implements Iterator +class ParentIterator extends FilterIterator implements RecursiveIterator -1) Iterators +2) Directories + +SPL offers two advanced directory classes. -Iterator is design pattern that allows to enumerate and list all elements of -a collection whatsoever using an oo protocol. The minimalistic Iterator needs -a method that returns the current value, a method that moves to the next value -and a method that checks whether or not the Iterator can provide more elements. - -In SPL this basich Iterator is defined by the interface spl_forward: - -interface spl_forward { - function current(); - function next(); - function has_more(); -} - -This basic Iterator does not allow to rewind itself nor does it in anyway -support to name the values by some kind association as key/value mappings -provided by the standard PHP arrays. All these additions to the basic Iterator -are done in specialized interfaces as described in detail in the file spl.php. - -SPL allows to hook into the engine opcodes that realize the foreach construct. -This construct normally works on arrays the following way. First it rewinds -the current array position to the beginning. Then it loops through the whole -array by first checking whether or not the end of the array is reached and -if not returning the current array value and or key. After that it move the -current array pointer forward and does starts the loop process again. As you -can see this perfectly maps to the interface spl_forward. So the foreach -hooking simply checks whether or not the variable passed to foreach is an -object of a class implementing the interface spl_forward. The foreach hook -can be activated by --enable-spl-foreach which is on by default. - -class it implements spl_forward... -$obj = new it(); -foreach($obj as $value) ... - -2) Arrays - -Arrays in general, not specifically PHP arrays, provide a collection of pairs -normally referred to as key and value. A PHP object consists of properties and -a class type specifing the methods available for the object. SPL now allows -this to be combined using the spl_array_<xy> interfaces. - -The minimalistic array interface is spl_array_read which only support reading: - -interface spl_array_read { - function exists($key); - function get($key); -} - -Any instance of a class that implements spl_array_read can be used with array -read notation when the corresponding hook is activated --enable-spl-array-read. - -class ar implements spl_array_read... -$obj = new ar(); -$value = $obj[$key]; - -SPL also supports the write notation by the interface spl_array_access: - -interface spl_array_access extends spl_array_read { - function set($value, $index); -} - -When the array write hook is activated by --enable-spl-array-write the -following can be done: - -class ar implements spl_array_access... -$obj = new ar(); -$value = $obj[$key]; -$obj[$key] = $value; - -However this hook should only be activated when it is made use of, since it -slows down noticeable. That is the case because first there is some not used -overhead and second the overhead is in one the most often used opcodes. \ No newline at end of file +class DirectoryIterator implements Iterator +class RecursiveDirectoryIterator extends DirectoryIterator implements RecursiveIterator Index: spl/spl.php diff -u spl/spl.php:1.10 spl/spl.php:1.11 --- spl/spl.php:1.10 Mon Aug 4 19:21:27 2003 +++ spl/spl.php Thu Dec 4 14:39:46 2003 @@ -1,340 +1,282 @@ <?php -/* Standard PHP Library +/** Standard PHP Library * - * (c) M.Boerger 2003 + * (c) Marcus Boerger, 2003 */ -/*! \brief Interface to foreach() construct +/** Abstract base interface that cannot be implemented alone. Instead it + * must be implemented by either IteratorAggregate or Iterator. * - * 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 class must implement the function new_iterator which must return - * an object which implements the interface spl_forward. - * - * \see spl_forward, spl_sequence, spl_forward_assoc, spl_sequence_assoc + * \note Internal classes that implement this interface can be used in a + * foreach construct and do not need to implement IteratorAggregate or + * Iterator. */ -interface spl_iterator { - - /*! \brief Create a new iterator - * - * \return an object that implements the interface spl_forward. +interface Traversable { +} + +/** Interface to create an external Iterator. + */ +interface IteratorAggregate implements Traversable { + /** Return an Iterator for the implementing object. */ - function new_iterator(); + function getIterator(); } -/*! \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_iterator, 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_iterator { - 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_iterator { - 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 for external iterators or objects that can be iterated + * themselves internally. */ -interface spl_forward { - - /*! \brief Retrieve the current currentent - * - * \return \c mixed current element or \c false if no more elements +interface Iterator implements Traversable { + /** Rewind the Iterator to the first element. */ - function current(); + function rewind(); - /*! \brief Forward to next element. + /** Return the current element. */ - function next(); + function current(); - /*! \brief Check if more elements are available. - * - * This method is meant to be called right after calls to rewind() or - * next(). When you use foreach hooking then this is done automatically - * but you can use it inside a for loop yourself: - * \code - for(; $it->has_more(); $it->next()) { ... } - \endcode - * - * \return \c bool whether or not more elements are available + /** Return the key of the current element. */ - 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 spl_sequence extends spl_forward { + function key(); - /*! Restart the sequence by positioning it to the first element. + /** Move forward to next element. */ - function rewind(); -} + function next(); -/*! \brief associative interface - * - * This interface allows to implement associative iterators - * and containers. - */ -interface spl_assoc { - - /*! \brief Retrieve the current elements key - * - * \return \c mixed current key or \c false if no more elements + /** Check if there is a current element after calls to rewind() or next(). */ - function key(); + function hasMore(); } -/*! \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 spl_assoc_forward implements spl_forward, spl_assoc { -} - -/*! \brief associative sequence - */ -interface spl_assoc_sequence implements spl_sequence, spl_assoc { -} - -/*! \brief array read only access for objects +/** Interface for recursive traversal to be used with + * RecursiveIteratorIterator. */ -interface spl_array_read { - - /*! Check whether or not the given index exists. - * The returned value is interpreted as converted to bool. - */ - function exists($index); +interface RecursiveIterator implements Iterator { + /** \return whether current element can be iterated itself. + */ + function hasChildren(); - /*! Read the value at position $index. - * This function is only beeing called if exists() returns true. + /** \return an object that recursively iterates the current element. + * This object must implement RecursiveIterator. */ - function get($index); + function getChildren(); } -/*! \brief array read/write access for objects. - * - * The following example shows how to use interface array_access: - * \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; - } - function del($index) { - unset($this->ar[$index]); - } - } - \endcode +/** Class for recursive traversal. The objects of this class are created by + * instances of RecursiveIterator. Elements of those iterators may be + * traversable themselves. If so these sub elements are recursed into. */ -interface spl_array_access implements spl_array_read { +class RecursiveIteratorIterator implements Iterator { + /** Construct an instance form a RecursiveIterator. + * + * \param $iterator inner root iterator + * \param $mode one of + * - RIT_LEAVES_ONLY do not return elements that can be recursed. + * - RIT_SELF_FIRST show elements before their sub elements. + * - RIT_CHILD_FIRST show elements after their sub elements- + * + * \note If you want to see only those elements which have sub elements then + * use a ParentIterator. + */ + function __construct(RecursiveIterator $iterator, $mode); - /*! Set the value identified by $index to $value. + /** \return the level of recursion (>=0). */ - function set($index, $value); + function getDepth(); - /*! Delete (unset) the value identified by $index. + /** \param $level the level of the sub iterator to return. + * \return the current inner sub iterator or the iterator at the + * specified $level. */ - function del($index); + function getSubIterator([$level]); } -/*! \brief An array wrapper +/** \brief An Array wrapper * * This array wrapper allows to recursively iterate over Arrays and Objects. * - * \see spl_array_it + * \see ArrayIterator */ -class spl_array implements spl_iterator { +class ArrayObject implements IteratorAggregate { - /*! Construct a new array iterator from anything that has a hash table. + /** Construct a new array iterator from anything that has a hash table. * That is any Array or Object. * * \param $array the array to use. */ function __construct($array); - /*! \copydoc spl_iterator::new_iterator + /** Get the iterator which is a ArrayIterator object connected to this + * object. */ - function new_iterator(); + function getIterator(); } -/*! \brief An array iterator +/** \brief An Array iterator * * This iterator allows to unset and modify values and keys while iterating * over Arrays and Objects. * - * To use this class you must instanciate spl_array. + * To use this class you must instanciate ArrayObject. */ -class spl_array_it implements spl_sequence_assoc { +class ArrayIterator implements Iterator { - /*! Construct a new array iterator from anything that has a hash table. + /** Construct a new array iterator from anything that has a hash table. * That is any Array or Object. * * \param $array the array to use. */ private function __construct($array); - /*! \copydoc spl_sequence::rewind + /** \copydoc Iterator::rewind + */ + function rewind(); + + /** \copydoc Iterator::current + */ + function current(); + + /** \copydoc Iterator::key + */ + function key(); + + /** \copydoc Iterator::next + */ + function next(); + + /** \copydoc Iterator::hasMore + */ + function hasMore(); +} + +abstract class FilterIterator implements Iterator { + /** Construct an instance form a Iterator. + * + * \param $iterator inner iterator + */ + function __construct(Iterator $iterator); + + /** \return whether the current element of the inner iterator should be + * used as a current element of this iterator or if it should be skipped. + */ + abstract function accept(); + + /** \copydoc Iterator::rewind */ function rewind(); - /*! \copydoc spl_forward::current + /** \copydoc Iterator::current */ function current(); - /*! \copydoc spl_assoc::key + /** \copydoc Iterator::key */ function key(); - /*! \copydoc spl_forward::next + /** \copydoc Iterator::next */ function next(); - /*! \copydoc spl_forward::has_more + /** \copydoc Iterator::hasMore */ - function has_more(); + function hasMore(); } -/*! \brief Directory iterator +class ParentIterator extends FilterIterator implements RecursiveIterator { + /** Construct an instance form a RecursiveIterator. + * + * \param $iterator inner iterator + */ + function __construct(RecursiveIterator $iterator); + + /** \copydoc RecursiveIterator::hasChildren + */ + function hasChildren(); + + /** \copydoc RecursiveIterator::getChildren + */ + function getChildren(); + + /** \copydoc Iterator::rewind + */ + function rewind(); + + /** \copydoc Iterator::current + */ + function current(); + + /** \copydoc Iterator::key + */ + function key(); + + /** \copydoc Iterator::next + */ + function next(); + + /** \copydoc Iterator::hasMore + */ + function hasMore(); +} + +/** \brief Directory iterator */ -class spl_dir implements spl_sequence { +class DirectoryIterator implements Iterator { - /*! Construct a directory iterator from a path-string. + /** Construct a directory iterator from a path-string. * * \param $path directory to iterate. */ function __construct($path); - /*! \copydoc spl_sequence::rewind + /** \copydoc Iterator::rewind */ function rewind(); - /*! \copydoc spl_forward::current + /** \copydoc Iterator::current */ function current(); - /*! \copydoc spl_forward::next + /** \copydoc Iterator::next */ function next(); - /*! \copydoc spl_forward::has_more + /** \copydoc Iterator::hasMore */ - function has_more(); + function hasMore(); - /*! \return The opened path. + /** \return The opened path. + */ + function getPath(); + + /** \return The current file name. */ - function get_path(); + function getFilename(); + + /** \return The current entries path and file name. + */ + function getPathname(); + + /** \return Whether the current entry is a directory. + */ + function isDir(); + + /** \return Whether the current entry is either '.' or '..'. + */ + function isDot(); +} + +/** \brief Directory iterator + */ +class RecursiveDirectoryIterator extends DirectoryIterator implements RecursiveIterator { + + /** \return whether the current is a directory (not '.' or '..'). + */ + function hasChildren(); + + /** \return a RecursiveDirectoryIterator for the current entry. + */ + function getChildren(); + } + ?> \ No newline at end of file Index: spl/examples/dba_array.php diff -u spl/examples/dba_array.php:1.2 spl/examples/dba_array.php:1.3 --- spl/examples/dba_array.php:1.2 Sat Nov 22 15:51:15 2003 +++ spl/examples/dba_array.php Thu Dec 4 14:39:46 2003 @@ -1,17 +1,29 @@ <?php -/* dba array utility +/** dba array utility * - * Usage php dba_dump <file> <handler> <key> [<value>] + * Usage php dba_array.php <file> <handler> <key> [<value>] * * If <value> is specified then <key> is set to <value> in <file>. * Else the value of <key> is printed only. * * Note: configure with --enable-dba * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 4) { + echo <<<EOF +Usage: php ${_SERVER['PHP_SELF']} <file> <handler> <key> [<value>] + +If <value> is specified then <key> is set to <value> in <file>. +Else the value of <key> is printed only. + + +EOF; + exit(1); +} + class DbaArray implements ArrayAccess { private $db; Index: spl/examples/dba_dump.php diff -u spl/examples/dba_dump.php:1.4 spl/examples/dba_dump.php:1.5 --- spl/examples/dba_dump.php:1.4 Sat Nov 22 15:51:15 2003 +++ spl/examples/dba_dump.php Thu Dec 4 14:39:46 2003 @@ -1,17 +1,29 @@ <?php -/* dba dump utility +/** dba dump utility * - * Usage: php dba_dump <file> <handler> [<regex>] + * Usage: php dba_dump.php <file> <handler> [<regex>] * * Show all groups in the ini file specified by <file>. * The regular expression <regex> is used to filter the by setting name. * * Note: configure with --enable-dba * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 3) { + echo <<<EOF +Usage: php ${_SERVER['PHP_SELF']} <file> <handler> [<regex>] + +Show all groups in the ini file specified by <file>. +The regular expression <regex> is used to filter the by setting name. + + +EOF; + exit(1); +} + require_once("dba_reader.inc"); require_once("key_filter.inc"); Index: spl/examples/directorytree.php diff -u spl/examples/directorytree.php:1.4 spl/examples/directorytree.php:1.5 --- spl/examples/directorytree.php:1.4 Sat Nov 22 15:51:15 2003 +++ spl/examples/directorytree.php Thu Dec 4 14:39:46 2003 @@ -2,13 +2,26 @@ /** tree view example * - * Usage: php DirectoryTree.php <path> + * Usage: php directorytree.php <path> [<start> [<count>]] * * Simply specify the path to tree with parameter <path>. * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 2) { + echo <<<EOF +Usage: php ${_SERVER['PHP_SELF']} <path> + +Displays a graphical directory tree for the given <path>. + +<path> The directory for which to generate the directory tree graph. + + +EOF; + exit(1); +} + $length = $argc > 3 ? $argv[3] : NULL; foreach(new LimitIterator(new DirectoryTreeIterator($argv[1]), @$argv[2], $length) as $file) { Index: spl/examples/findfile.php diff -u spl/examples/findfile.php:1.2 spl/examples/findfile.php:1.3 --- spl/examples/findfile.php:1.2 Sat Nov 22 15:51:15 2003 +++ spl/examples/findfile.php Thu Dec 4 14:39:46 2003 @@ -1,6 +1,30 @@ <?php -class FindFile extends SearchIterator +/** Find a specific file by name. + * + * Usage: php findfile.php <path> <name> + * + * <path> Path to search in. + * <name> Filename to look for. + * + * (c) Marcus Boerger, 2003 + */ + +if ($argc < 3) { + echo <<<EOF +Usage: php findfile.php <file> <name> + +Find a specific file by name. + +<path> Path to search in. +<name> Filename to look for. + + +EOF; + exit(1); +} + +class FindFile extends FilterIterator { protected $file; Index: spl/examples/ini_groups.php diff -u spl/examples/ini_groups.php:1.1 spl/examples/ini_groups.php:1.2 --- spl/examples/ini_groups.php:1.1 Wed Jul 16 17:52:03 2003 +++ spl/examples/ini_groups.php Thu Dec 4 14:39:46 2003 @@ -1,17 +1,29 @@ <?php -/* List groups within an ini file +/** List groups within an ini file * - * Usage: php dba_dump <file> [<regex>] + * Usage: php dba_dump.php <file> [<regex>] * * Show all groups in the ini file specified by <file>. * The regular expression <regex> is used to filter the result. * * Note: configure with --enable-dba * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 2) { + echo <<<EOF +Usage: php dba_dump.php <file> [<regex>] + +Show all groups in the ini file specified by <file>. +The regular expression <regex> is used to filter the result. + + +EOF; + exit(1); +} + require_once("dba_reader.inc"); require_once("key_filter.inc"); @@ -58,6 +70,7 @@ if ($argc>2) { $it = new key_filter($it, $argv[2]); } + foreach($it as $group) { echo "$group\n"; } Index: spl/examples/tree.php diff -u spl/examples/tree.php:1.5 spl/examples/tree.php:1.6 --- spl/examples/tree.php:1.5 Sat Nov 22 15:51:15 2003 +++ spl/examples/tree.php Thu Dec 4 14:39:46 2003 @@ -2,13 +2,30 @@ /** tree view example * - * Usage: php Tree.php <path> + * Usage: php tree.php <path> * * Simply specify the path to tree with parameter <path>. * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +// The following line only operates on classes which are converted to c already. +// But does not generate a graphical output. +//foreach(new RecursiveIteratorIterator(new ParentIterator(new RecursiveDirectoryIterator($argv[1])), 1) as $file) { + +if ($argc < 2) { + echo <<<EOF +Usage: php ${_SERVER['PHP_SELF']} <path> + +Displays a graphical tree for the given <path>. + +<path> The directory for which to generate the tree graph. + + +EOF; + exit(1); +} + foreach(new DirectoryGraphIterator($argv[1]) as $file) { echo $file . "\n"; } Index: spl/examples/autoload.inc +++ spl/examples/autoload.inc <?php function __autoload($file) { require_once(dirname($_SERVER['PATH_TRANSLATED']).'/'.strtolower($file).'.inc'); } ?>
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php