mirror of
https://github.com/php/php-src.git
synced 2024-11-26 19:33:55 +08:00
Put some brief technically description here
This commit is contained in:
parent
bc4c7c6a6d
commit
20b8a7dfe4
102
ext/spl/README
102
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 (<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.
|
Loading…
Reference in New Issue
Block a user