ID: 28444
Comment by: alexei at net24 dot co dot nz
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:
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;
Previous Comments:
------------------------------------------------------------------------
[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.
------------------------------------------------------------------------
[2004-05-27 12:15:55] [EMAIL PROTECTED]
The problem here is that it is unclear what actually should happen in
this case. When executing $y->x->x = 3, we need to fetch $y->x for
writing, i.e., get zval** of it. However, only handler that could give
it to us is get_property_ptr_ptr and it is not overridable.
We probably could use the result of __get, though it would mean we
would have to fake zval**, which could have some strange consequences -
needs to be checked.
------------------------------------------------------------------------
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