[PHP] [PHP5] paradox ? Bug ?
Hello - I think there is a bug or a paradox in the php 5 object model implementation. This is an example : ?php class foo implements arrayAccess { private $array = array(); function __construct() {} function __get($key) { return $this-offsetGet($key); } function __set($key, $value) { $this-offsetSet($key, $value); } function offsetExists($key) { return isset($this-array[$key]); } function offsetGet($key) { return $this-array[$key]; } function offsetSet($key, $value) { $this-array[$key] = $value; } function offsetUnset($key) { unset($this-array[$key]; } } $foo = new foo(); echo (isset($foo['bar']) == true ? 'set' : 'not set'); $foo['bar'] = 'bar'; echo (isset($foo['bar']) == true ? 'set' : 'not set'); echo $foo['bar']; #Expected result : # not set # set # bar #Real result # not set # set # bar # !! GREAT !! #Now, the same thing with __get() and __set() unset($foo); $foo = new foo(); echo (isset($foo-array) == true ? 'array is set' : 'array is not set'); echo (isset($foo-bar) == true ? 'bar is set' : 'bar is not set'); $foo-bar = 'bar'; echo (isset($foo['bar']) == true ? 'bar is set' : 'bar is not set'); echo $foo-bar; #Expected result : # array is set # bar is not set # bar is set # bar #Real result # array is set # Ok ! # bar is not set # Ok ! # bar is not set # PROBLEM PROBLEM # bar # !! NOT GREAT !! ? It is very strange. isset() does not return the good value on property wich was set with __set() !! But isset() return the good value on property wich was set in the class !! And isset() return the good value on value wich was set with offsetSet() method !! It is a paradox ! I think that isset MUST return the same value in all case. What do you think of ? Fred. Warning : the php code may be wrong (parse error...), i can not validate it in php5 currently -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] [PHP5] paradox ? Bug ?
Frédéric Hardy wrote: Hello - I think there is a bug or a paradox in the php 5 object model implementation. This is an example : ?php class foo implements arrayAccess { private $array = array(); function __construct() {} function __get($key) { return $this-offsetGet($key); } function __set($key, $value) { $this-offsetSet($key, $value); } function offsetExists($key) { return isset($this-array[$key]); } function offsetGet($key) { return $this-array[$key]; } function offsetSet($key, $value) { $this-array[$key] = $value; } function offsetUnset($key) { unset($this-array[$key]; } } $foo = new foo(); echo (isset($foo['bar']) == true ? 'set' : 'not set'); $foo['bar'] = 'bar'; echo (isset($foo['bar']) == true ? 'set' : 'not set'); echo $foo['bar']; #Expected result : # not set # set # bar #Real result # not set # set # bar # !! GREAT !! #Now, the same thing with __get() and __set() unset($foo); $foo = new foo(); echo (isset($foo-array) == true ? 'array is set' : 'array is not set'); echo (isset($foo-bar) == true ? 'bar is set' : 'bar is not set'); $foo-bar = 'bar'; echo (isset($foo['bar']) == true ? 'bar is set' : 'bar is not set'); echo $foo-bar; #Expected result : # array is set # bar is not set # bar is set # bar #Real result # array is set # Ok ! # bar is not set # Ok ! # bar is not set # PROBLEM PROBLEM # bar # !! NOT GREAT !! ? It is very strange. isset() does not return the good value on property wich was set with __set() !! But isset() return the good value on property wich was set in the class !! And isset() return the good value on value wich was set with offsetSet() method !! It is a paradox ! I think that isset MUST return the same value in all case. What do you think of ? Fred. See recent discusion on this list about this behavior. You can find it in the archives if you look for __isset. Anyways, line echo (isset($foo-array) == true ? 'array is set' : 'array is not set'); should give you this fatal error: Fatal error: Cannot access private property foo::$array in ... -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] [PHP5] paradox ? Bug ?
Marek Kilimajer wrote: See recent discusion on this list about this behavior. You can find it in the archives if you look for __isset. I know, I am the author of this recent discussion. Current discussion is an extension. echo (isset($foo-array) == true ? 'array is set' : 'array is not set'); should give you this fatal error: Fatal error: Cannot access private property foo::$array in ... Yes. I am agree with you. Add a public property in foo class and replace isset($foo-array) by your public property. Fred. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] [PHP5] paradox ? Bug ?
Frédéric Hardy wrote: Marek Kilimajer wrote: See recent discusion on this list about this behavior. You can find it in the archives if you look for __isset. I know, I am the author of this recent discussion. Current discussion is an extension. isset($foo['bar']) tests for existance of $foo['bar'], however, you created $foo-array['bar'] in you __set() method. It's the same as before - isset() does not call __get(). -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP] [PHP5] paradox ? Bug ?
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
Re: [PHP] [PHP5] paradox ? Bug ?
* Thus wrote Daniel Schierbeck: 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): The issue of isset() on __get and __set, will most likely be fixed with 5.1. Curt -- The above comments may offend you. flame at will. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php