Re: [PHP5] paradox ? Bug ?
| From: | Daniel Schierbeck | Date: | Fri, 03 Sep 2004 14:10:33 +0000 |
| Subject: | Re: [PHP5] paradox ? Bug ? | ||
| References: | 1 2 3 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-195730@lists.php.net to get a copy of this message | ||
I think this basically sums up the problems of the current handling of existence-checking in overloaded objects: We have an object that has user-defined methods for getting and setting object properties (__get() and __set(), respectively). These methods get and set the properties in a private array (private: can only be access from within the object itself). Example (mostly stolen from php.net):
<?php
class Foo
{
// This array holds the properties
private $elem = array();
// This method is automatically called when an
// undefined (or inaccessible, as $array) property is
// called. The name of the called property is the only
// argument.
public function __get ($prop)
{
if (isset($this->elem[$prop])) {
return $this->elem[$prop];
} else {
trigger_error("Oooops", E_USER_WARNING);
}
}
// Same as before, but is called when setting a
// property
public function __set ($prop, $val)
{
$this->elem[$prop] = $val;
}
}
// Instantiate the class
$foo = new Foo();
// Check if $foo->bar ($foo->elem['bar']) is set
if (isset($foo->bar)) {
echo "\$bar is set\n";
} else {
echo "\$bar is not set\n";
}
// Set $foo->bar to 'foobar'
$foo->bar = 'foobar';
// Print the value of $foo->bar
echo $foo->bar, "\n"; // foobar
// Check if $foo->bar ($foo->elem['bar']) is set
if (isset($foo->bar)) {
echo "\$bar is set\n";
} else {
echo "\$bar is not set\n";
}
?>
Now, since we access the properties of $foo in a 'virtual' manner - meaning $foo->bar doesn't really exist, it's actually $foo->elem['bar'] (if it were public, that is) - we can assume that we can check for property existance in the same 'virtual' way, right? Wrong. If we could, the above would output this:
$bar is not set
foobar
$bar is set
Yet it returns:
$bar is not set
foobar
$bar is not set
If we want to check whether or not $bar exists in $foo, we have to add a method to the Foo class:
public function isSet ($prop)
{
if (isset($this->elem[$prop])) {
return TRUE;
} else {
return FALSE;
}
}
Which is rather dumb, considering that the intention of isset() is to check whether or not a variable exists!
So far there has been two suggestions as to what can be done:
1. Change isset so that it automatically detects
overloaded properties
2. Let the user define a custom __isSet() method, similar to the one above, that is called each time a property of the class
is checked with isset()
Maybe there's some other angles/ideas/suggestions?
--
Daniel Schierbeck