Hi,

On May 7, 2008, at 2:12 AM, Jeff Moore wrote:

> Specifying the accessor methods in an interface reveals too much of
> the implementation.  Properties (the kind with accessor methods) are
> themselves an abstract concept.  You want to be able to take an
> interface definition such as:
>
> interface foo {
>       public $bar;  // if you prefer this to abstract $foo;
> }
>
> and implement it like this:
>
> class DoIt implements foo {
>       public $bar;
> }
>
> or to implement it using setters, using your notation:
>
> class DoIt2 implements foo {
>       public $foo {
>               public function get();
>               protected function set($value); 
>       }
> }
>
> The whole point of this kind of property is that the caller is never
> supposed to know if they are just accessing a object instance variable
> or an accessor method.  This is called the uniform access principle.
> http://en.wikipedia.org/wiki/Uniform_access_principle

I like this concept, so I extended it and wrote some code
("SimplePDO") showing my ideas. You can see it here:
http://internals.php.pastebin.com/f6a3cc2f

This way, every property can have 0 - 6 functions, that change methods
of accessing it:
void load()   // (made for simple lazy-loading)
typeof(property) get()
void validate(mixed $value) throws InvalidValueException
typeof(property) set(typeof(property) $value)
bool isset()
void unset()

They are called in this way:

PHP code:
echo $object->property;

What PHP does behind the scenes (in PHP-based pseudocode, somebody
will have to write it in C for Zend Engine):
$object = $object;
$property = 'property';

if (!property_is_readable($object->$property))
{
        throw new PropertyNotReadableException($object, $property)
}

if (is_null($object->$property.realValue))
{
        try
        {
                $object->$property.load();
        }
        catch (UndefinedPropertyMethodException $e) {}
}

try
{
        return $object->$property.get();
}
catch (UndefinedPropertyMethodException $e)
{
        return $object->$property.realValue;
}



PHP code:
$object->property = 'new value';

What PHP does behind the scenes:
$object = $object;
$property = 'property';
$newValue = 'new value';

if (!property_is_writable($object->$property))
{
        throw new PropertyNotWritableException($object, $property)
}

try
{
        $object->$property.validate($newValue);
}
catch (UndefinedPropertyMethodException $e) {}
/* Does not catch InvalidValueException */

try
{
        return $object->$property.set($newValue);
}
catch (UndefinedPropertyMethodException $e)
{
        return $object->$property.realValue = $newValue;
}



PHP code:
isset($object->property);

What PHP does behind the scenes:
$object = $object;
$property = 'property';

if (!property_is_readable($object->$property))
{
        return false;
}

try
{
        return $object->$property.isset();
}
catch (UndefinedPropertyMethodException $e)
{
        return (is_null($object->$property.realValue)) ? false : true;
}



PHP code:
unset($object->property);

What PHP does behind the scenes:
$object = $object;
$property = 'property';

if (!property_is_writable($object->$property))
{
        throw new PropertyNotWritableException($object, $property)
}

try
{
        $object->$property.unset();
}
catch (UndefinedPropertyMethodException $e)
{
        try
        {
                $object->$property.set(null);
        }
        catch (UndefinedPropertyMethodException $e)
        {
                $object->$property.realValue = null;
        }
}



property_is_readable() and property_is_writable() language constructs
check if property is readable/writable in current context.

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

Reply via email to