Hey,

I'd like to talk about merging SPL into the engine, or at least taking
some of the core components of SPL and adapting them to the engine, so
that the same functionality is available per-default in PHP5.

SPL provides a standard set of interfaces, specifically:

Iterator:

Allows you to override the foreach construct to work on your object.

interface spl_forward {
  function current();
  function next();
  function has_more();
}

class foo implements spl_forward { }
$f = new foo;
foreach ($f as $e) { }

Array

spl_array_read allows you to overload reading elements from an array.

interface spl_array_read {
    function exists($key);
    function get($key);
}


spl_array_access allows you to overload writes as well as reads:

interface spl_array_access implements spl_array_read {
    function set($value, $index);
}


The way I look at it, SPL has to important concepts that we should look
at integrating in to Zend Engine 2/PHP5:

1) Overloading objects as arrays.  This is a crucial feature when
interfacing with external sources, like java, or .net, or even a db
extension.  It allows you to lazy initialize all data coming from an
external source, only taking what you need.  Further, there is no need
to drink the OO kool-aid, in order to take advantage of this feature.

2) The use of interfaces to ascertain whether or not an object supports
a given feature set.  The usage of interfaces is good for three
reasons.  First it is much faster than our current method of checking
whether a method exists or not.  Second it allows us to have coherent
method names (no double underscore), without risking any backwards
compatibility isues.  Thirdly, it makes it more clear that a class is
overloaded, and allows you to simply check for overloads.

Therefore, when I talk about integrating SPL and PHP, I think the
following steps should be taken:

1) "Fix" the object overloading model to allow you to handle array
accesses internally.  This includes the iterator concept and and array
read and write.  This portion of the code would be an integral part of
the overloading mechanism (no interfaces required).

2) Export and revise the userspace implementation of overloading, using
interfaces to define when and how a object is overloaded.  I propose
something along the lines of (this stuff isn't original, just
formalized) ::

// Base overload interface, to allow for checks on whether or not a 
// object is overloaded
interface Overloaded { };

// Overloaded_Value overloads the object itself, allowing you to treat 
// the object as a base type
interface Overloaded_Value implements Overloaded {
    // Called when the object is directly assigned to
    // @return null
    function setValue($value);

    // Called when the object is cast to type a certain type
    // or kind-of type
    // valid types are ::
    //     'boolean'
    //     'integer'
    //     'double'
    //     'number'
    //     'string'
    //     'array'
    // @return value A value of type $type
    function asType($type);
};

// Overloaded_Iterator allows you to overload an object, to allow
// foreach () to move over the object
interface Overloaded_Iterator implements Overloaded {
    // Move forward one element in the object
    // @return null
    function next();
    // Get the value of the current object
    // @return zval (a PHP value)
    function current();
    // Tells whether or not the object has more data
    // @return bool
    function hasMore();
};

// Overloaded properties allows you to overload both property
// *and* array accesses.
interface Overloaded_Properties implements Overloaded {
    // Get $property
    // @return zval (a PHP value)
    function get($property);
    // Set $property
    // @return nothing
    function set($property, $value);
    // Check whether or not $property exists
    // @return bool
    function exists($property);
}

// Allow you to overload method calls
interface Overloaded_Methods implements Overloaded {
    // Catch a method call, $name is the name of the method
    // @return zval (a PHP value) 
    function call($name);
};


Thoughts?  This should be relatively easy to implement (although I'm not sure on the 
timing with regards 
to the beta), and after thinking about it, this just seems like the way to do it.

-Sterling

PS: 95% of this message is just building on prior art.  Zeev and Andi's prior
art, and marcus's prior art.  All credit to them :)

-- 
Good judgement comes from experience, and experience comes from 
bad judgement. 
    - Fred Brooks

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to