diff --git a/ext/spl/README b/ext/spl/README index 5d12e7d42f2..60c6d97425c 100755 --- a/ext/spl/README +++ b/ext/spl/README @@ -1,36 +1,88 @@ This is an extension that aims to implement some efficient data access -interfaces and classes. +interfaces and classes. You'll find the classes documented using php +code in the file spl.php. -SPL allows to hook into foreach. Doing so you can do something like -this: +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. - $obj = new whatever(); - foreach($obj as $key => $value) { ... } +Look into the examples subdirectory for some basic examples which will +demonstracte this. -This is meant to be used for database access. For example you could -grab my patch to sqlite (http://marcus-boerger.de/php/ext/sqlite/) and -look at the oo tests: +Also some classes of extensions like SQLite inherit SPL interfaces so that +they take advantage of the foreach or array overloading. - $db = new sqlite($filename); - foreach($db->query("SELECT....") as $row) { ... } +1) Iterators -SQLite offers four access strategies: -1) sqlite_query + sqlite_fetch_array -2) sqlite_unbuffered_query + sqlite_fetch_array -3) sqlite_query + iterators (sqlite_current) -4) sqlite_unbuffered_query + iterators (sqlite_current) +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. -1) and 3) do "over eager evaluating" since they fetch all rows directly. +In SPL this basich Iterator is defined by the interface spl_forward: -2) does "eager evaluating". It always fetches the next row but doesn't -keep the current row, so that it must be stored elsewhere if it must be -accessed more then once. For instance this happens when you need to access -columns separately. +interface spl_forward { + function current(); + function next(); + function has_more(); +} -4) does "eager evaluating". But in contrast to 2) it keeps the current row -hence its name. +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. -There is no efficient way for "lazy or just in time evaluating" so 4) should -be the best case. And 4) also enables the foreach trick. +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. -To implement 3) and 4) with other db extensions ask me and wait for LT to pass. +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: + +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