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