ID: 28444 User updated by: dennis at inmarket dot lviv dot ua Reported By: dennis at inmarket dot lviv dot ua Status: Analyzed Bug Type: Class/Object related Operating System: WinXP PHP Version: 5.0.0RC2 New Comment:
In my opinion, such "workarounds" should be replaced by fixing the issue in PHP itself. Indeed, it is funny that this works for getting properties, and doesn't for setting. Onother question: how did PHP5 make for a release with this core level bug? Previous Comments: ------------------------------------------------------------------------ [2004-08-05 07:20:16] alexei at net24 dot co dot nz another "workaround", it allows to use this feature now and to convert scripts later when this feature is available in php. class a { function __call ($property, $args){ return __get($property); } use it like this: $a->b->c=10; as $a->b()->c=10; echo $a->b->c; as echo $a->b()->c; ------------------------------------------------------------------------ [2004-08-05 06:48:18] alexei at net24 dot co dot nz it allows to read value referenced by $a->b->c but it does not allow to modify it, that's makes the whole thing inconsistent... workaround like below does the job, but it is ugly! $b=$a->b; $b->c=5; i think if ->-> is called it should call __get methods at all each stage and pass reference to the next -> operation ------------------------------------------------------------------------ [2004-06-30 04:21:46] ryan dot harris at gmail dot com A good solution would be to have a way of doing a "pre-set" routine i.e. __get($propertyname, $pre_set = true) and that routine is expected to return a valid object or the "Cannot access undefined..." will automatically result. Some more example code that causes the problem (no way of testing to see if the concept is correct - since this message keeps appearing): class Setting { private $mSettings; function __construct() { $constructor_args = func_get_args(); if (isset($constructor_args[0])) { $this->mSettings = array("_defaultValue"=>$constructor_args[0]); } else $this->mSettings = array("_defaultValue"=>null); } function __get($propertyName) { print "[$propertyName]<br>\n"; if ($propertyName == "_settingCount") { return count($this->mSettings) - 1; } elseif ($propertyName == "_valueNames") { //return $this->GetValueNames(); } elseif ($propertyName == "_keyNames") { //return $this->GetValueNames(); } elseif ($propertyName == "_defaultValue") { print_r($this->mSettings); return $this->mSettings["_defaultValue"]; } // It's none of the special properties. if (isset($this->mSettings[$propertyName])) { return $this->mSettings[$propertyName]; } else { // If we had the $pre_set we could do this: if ($pre_set) { // initialize for a set $this->mSettings[$propertyName] = new Setting(); return $this->mSettings[$propertyName]; } else throw new Exception("Undefined setting name."); } } function __set($propertyName, $propertyValue) { print "[$propertyName]<br>\n"; switch ($propertyName) { case "_settingCount": case "_valueNames": case "_keyNames": throw Exception("Property is read only."); break; case "_defaultValue": $this->mSettings["_defaultValue"] = $propertyValue; break; default: if (!isset($this->mSettings[$propertyName])) $this->mSettings[$propertyName] = new Setting($propertyValue); else $this->mSettings[$propertyName]->_defaultValue = $propertyValue; break; } // switch } } This code if it worked would let you do the following: $t = new Setting(); $t->includes->_defaultValue = "Automated" $t->includes->automatedIncludes->includeDirectory = "c:/includes" $t->includes->automatedIncludes = "oncePerFile" $t->includes->manualIncludes->includeDirectory = "c:/php" Which would represent: includes = Automated --> automatedIncludes = oncePerFile --> includeDirectory = c:/includes --> manualIncludes --> includeDirectory = c:/php in a lightweight manner. The layers would be created as they are needed and all with an elegant method. ------------------------------------------------------------------------ [2004-06-14 20:24:14] cunha17 at uol dot com dot br This odd behavior is still present in latest CVS and happens in Linux also. Cristiano Duarte ------------------------------------------------------------------------ [2004-05-27 16:11:39] dennis at inmarket dot lviv dot ua Well, I am not familiar with the engine code, but it works for getting "undefined property for object with overloaded property access", as the reproduce code clearly shows. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/28444 -- Edit this bug report at http://bugs.php.net/?id=28444&edit=1