Put some brief technically description here

This commit is contained in:
Marcus Boerger 2003-06-23 22:37:12 +00:00
parent bc4c7c6a6d
commit 20b8a7dfe4

View File

@ -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 (<a href="http://marcus-boerger.de/php/ext/sqlite/">http://marcus-boerger.de/php/ext/sqlite/</a>) 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_<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.