From: Marcus Boerger Date: Thu, 4 Dec 2003 19:39:46 +0000 (+0000) Subject: Update documentation X-Git-Tag: php-5.0.0b3RC1~319 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f679b5c935f713854a14f00370d4d832a4850b56;p=php Update documentation --- diff --git a/ext/spl/README b/ext/spl/README index 60c6d97425..99f34af679 100755 --- a/ext/spl/README +++ b/ext/spl/README @@ -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. -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. - -Look into the examples subdirectory for some basic examples which will -demonstracte this. - -Also some classes of extensions like SQLite inherit SPL interfaces so that -they take advantage of the foreach or array overloading. +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. 1) Iterators -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_ 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: +SPL offers some advanced iterator algorythmns: -interface spl_array_access extends spl_array_read { - function set($value, $index); -} +interface RecursiveIterator implements Iterator +class RecursiveIteratorIterator implements Iterator +abstract class FilterIterator implements Iterator +class ParentIterator extends FilterIterator implements RecursiveIterator -When the array write hook is activated by --enable-spl-array-write the -following can be done: +2) Directories -class ar implements spl_array_access... -$obj = new ar(); -$value = $obj[$key]; -$obj[$key] = $value; +SPL offers two advanced directory classes. -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 diff --git a/ext/spl/examples/autoload.inc b/ext/spl/examples/autoload.inc new file mode 100755 index 0000000000..632ab8e4e8 --- /dev/null +++ b/ext/spl/examples/autoload.inc @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/ext/spl/examples/dba_array.php b/ext/spl/examples/dba_array.php index bd73ce2a0d..931e3cfb92 100755 --- a/ext/spl/examples/dba_array.php +++ b/ext/spl/examples/dba_array.php @@ -1,17 +1,29 @@ [] + * Usage php dba_array.php [] * * If is specified then is set to in . * Else the value of is printed only. * * Note: configure with --enable-dba * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 4) { + echo << [] + +If is specified then is set to in . +Else the value of is printed only. + + +EOF; + exit(1); +} + class DbaArray implements ArrayAccess { private $db; diff --git a/ext/spl/examples/dba_dump.php b/ext/spl/examples/dba_dump.php index 04efdf4d88..b608c9fe63 100755 --- a/ext/spl/examples/dba_dump.php +++ b/ext/spl/examples/dba_dump.php @@ -1,17 +1,29 @@ [] + * Usage: php dba_dump.php [] * * Show all groups in the ini file specified by . * The regular expression is used to filter the by setting name. * * Note: configure with --enable-dba * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 3) { + echo << [] + +Show all groups in the ini file specified by . +The regular expression is used to filter the by setting name. + + +EOF; + exit(1); +} + require_once("dba_reader.inc"); require_once("key_filter.inc"); diff --git a/ext/spl/examples/directorytree.php b/ext/spl/examples/directorytree.php index e22244a9e1..31af2495a7 100755 --- a/ext/spl/examples/directorytree.php +++ b/ext/spl/examples/directorytree.php @@ -2,13 +2,26 @@ /** tree view example * - * Usage: php DirectoryTree.php + * Usage: php directorytree.php [ []] * * Simply specify the path to tree with parameter . * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 2) { + echo << + +Displays a graphical directory tree for the given . + + 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) { diff --git a/ext/spl/examples/findfile.php b/ext/spl/examples/findfile.php index dc23c5a032..5cdd0dc893 100755 --- a/ext/spl/examples/findfile.php +++ b/ext/spl/examples/findfile.php @@ -1,6 +1,30 @@ + * + * Path to search in. + * Filename to look for. + * + * (c) Marcus Boerger, 2003 + */ + +if ($argc < 3) { + echo << + +Find a specific file by name. + + Path to search in. + Filename to look for. + + +EOF; + exit(1); +} + +class FindFile extends FilterIterator { protected $file; diff --git a/ext/spl/examples/ini_groups.php b/ext/spl/examples/ini_groups.php index 1909e87c2d..7ebdaed7f9 100755 --- a/ext/spl/examples/ini_groups.php +++ b/ext/spl/examples/ini_groups.php @@ -1,17 +1,29 @@ [] + * Usage: php dba_dump.php [] * * Show all groups in the ini file specified by . * The regular expression is used to filter the result. * * Note: configure with --enable-dba * - * (c) Marcus Boerger + * (c) Marcus Boerger, 2003 */ +if ($argc < 2) { + echo << [] + +Show all groups in the ini file specified by . +The regular expression is used to filter the result. + + +EOF; + exit(1); +} + require_once("dba_reader.inc"); require_once("key_filter.inc"); @@ -58,6 +70,7 @@ $it = new ini_groups($argv[1]); if ($argc>2) { $it = new key_filter($it, $argv[2]); } + foreach($it as $group) { echo "$group\n"; } diff --git a/ext/spl/examples/tree.php b/ext/spl/examples/tree.php index 0dc7c056f8..0ade2dd3ec 100755 --- a/ext/spl/examples/tree.php +++ b/ext/spl/examples/tree.php @@ -2,13 +2,30 @@ /** tree view example * - * Usage: php Tree.php + * Usage: php tree.php * * Simply specify the path to tree with parameter . * - * (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 << + +Displays a graphical tree for the given . + + The directory for which to generate the tree graph. + + +EOF; + exit(1); +} + foreach(new DirectoryGraphIterator($argv[1]) as $file) { echo $file . "\n"; } diff --git a/ext/spl/spl.php b/ext/spl/spl.php index 2edde96154..172660f13e 100755 --- a/ext/spl/spl.php +++ b/ext/spl/spl.php @@ -1,340 +1,282 @@ 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 spl_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. +/** Interface to create an external Iterator. + */ +interface IteratorAggregate implements Traversable { + /** Return an Iterator for the implementing object. */ - function next(); - - /*! \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 - */ - function has_more(); + function getIterator(); } -/*! \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 for external iterators or objects that can be iterated + * themselves internally. */ -interface spl_sequence extends spl_forward { - - /*! Restart the sequence by positioning it to the first element. +interface Iterator implements Traversable { + /** Rewind the Iterator to the first element. */ function rewind(); -} -/*! \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 + /** Return the current element. + */ + function current(); + + /** Return the key of the current element. */ 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 spl_assoc_forward implements spl_forward, spl_assoc { -} + /** Move forward to next element. + */ + function next(); -/*! \brief associative sequence - */ -interface spl_assoc_sequence implements spl_sequence, spl_assoc { + /** Check if there is a current element after calls to rewind() or next(). + */ + function hasMore(); } -/*! \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 getFilename(); + + /** \return The current entries path and file name. */ - function get_path(); + 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