|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2004-08-31 16:00 UTC] dasch at ulmail dot net
Description:
------------
When trying to determine whether or not a property in an overloaded object is set, isset() always returns FALSE. This is not the case with objects that isn't overloaded (doesn't have a __get() method defined).
Reproduce code:
---------------
<?php
class OO
{
private $elem = array("a" => 1);
public function __get ($prop)
{
if (isset($this->elem[$prop])) {
return $this->elem[$prop];
} else {
return NULL;
}
}
public function __set ($prop, $val)
{
$this->elem[$prop] = $val;
}
}
$o = new OO();
echo isset($o->a) ? "yes\n" : "no\n";
echo isset($o->b) ? "yes\n" : "no\n";
echo is_null($o->a) ? "yes\n" : "no\n";
echo is_null($o->b) ? "yes\n" : "no\n";
?>
Expected result:
----------------
yes
no
no
yes
Actual result:
--------------
no
no
no
yes
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 28 07:00:01 2025 UTC |
This works fine for me: derick@kossu:~$ cat bug29917.php <?php class oo { var $a; } $o = new oo; echo isset($o->a) ? "yes\n" : "no\n"; $o->a = 'bar'; echo isset($o->a) ? "yes\n" : "no\n"; ?> derick@kossu:~$ php bug29917.php no yes Come up with a short example like mine that shows that it doesn't work. Just saying $o->a won't work doesn't help.<?php class OO { private $array = array(); function __construct() {} function __set($name, $value) { $this->array[$name] = $value; } function __get($name) { if (isset($this->array[$name]) == true) return null; else return $this->array[$name]; } } $o = new oo(); $o->foo = 'bar'; echo (isset($o->foo) == true ? 'foo is set' : 'foo is not set'); #Expecting result # => foo is set #Real result # => foo is not set ?> If PHP provide __set() and __get() function in order to create property dynamicaly, PHP function like isset() MUST BE USED with these "dynamic" properties as usual. So, in my example, isset() MUST return TRUE !! and not FALSE !!If the isset() function aren't going to work with properties accessed with a __get() call, then there should at least be a __isset() method that allows for custom isset()-handling. eg: <?php class Foo { private $bar = "bar"; public function __isset ($prop) { if (isset($this->$prop)) { return TRUE; } else { return FALSE; } } } $foo = new Foo(); echo isset($foo->bar) ? "yes\n" : "no\n"; // Should be the same as echo $foo->__isset('bar') ? "yes\n" : "no\n"; ?><?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 abnormal ! isset() does not return the good value on property wich was set with __set() it is 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.