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

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Reply via email to