# Integrating SPL

- Thread: https://externals.io/message/2800
- Original archive: https://news-web.php.net/php.internals/2800
- Started by Sterling Hughes on 2003-06-25T21:59:09+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #2800 — Sterling Hughes — 2003-06-25T21:59:09+00:00

URL: https://externals.io/message/2800#2800

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

---

## #2829 — Andrei Zmievski — 2003-06-26T13:14:34+00:00

URL: https://externals.io/message/2800#2829 · In reply to: #2800

> 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).

Please - I've been asking for this feature for god knows how long now. I
very much hope this is done soon, because PHP-GTK requires it.

-Andrei
* "I'll need daily status reports on why you're so behind." -- Dilbert's boss *

---

## #2878 — Andi Gutmans — 2003-06-27T07:53:50+00:00

URL: https://externals.io/message/2800#2878 · In reply to: #2800

Hey,

In general I think the ideas behind SPL are interesting. However, my main 
problem with the whole array and iterator overloading is that it's not 
quite clear to me where this should have an effect. Will it only work in 
foreach()? Is it supposed to work in array_sort() and all other internal 
functions? Is it supposed to work with assignment of the array() construct 
to an object?
You can see where I am heading... I don't have the answers and I think we 
might end up in one big mess...

About the use of interfaces for implementing methods such as __call(). This 
might be sexier but in many cases it won't improve performance (I think). 
For example, __call() only gets called if the first function lookup failed. 
Once that happens we just check if ce has a __call function ptr. Searching 
the class tree for the Callable_Overload (or whatever you want to call it) 
interface will not be as quick, or in the least not quicker.

A bit of a mess email but I hope I gave you guys some food for thought. 
Please think about these issues carefully before replying.
In general, I don't think this should effect the release date of the beta.

Got to run now.
Andi

At 05:59 PM 25/6/2003 -0400, Sterling Hughes wrote:
>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
