Bug #69220 [Nab]: _call, __construct, __set
| From: | requinix@php.net | Date: | Fri, 13 Mar 2015 07:11:17 +0000 |
| Subject: | Bug #69220 [Nab]: _call, __construct, __set | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-191365@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=69220&edit=1
ID: 69220
Updated by: requinix@php.net
Reported by: cybermerlin at ya dot ru
Summary: _call, __construct, __set
Status: Not a bug
Type: Bug
Package: Class/Object related
Operating System: winx64_8.1
PHP Version: 5.6.6
Block user comment: N
Private report: N
New Comment:
http://php.net/manual/en/language.oop5.overloading.php#object.call
>__call() is triggered when invoking inaccessible methods in an object context.
Previous Comments:
------------------------------------------------------------------------
[2015-03-13 06:22:15] cybermerlin at ya dot ru
I was expecting at least the message of two calls: setField1 and hasField1.
why there is no information about the call setField1?
------------------------------------------------------------------------
[2015-03-13 02:03:53] requinix@php.net
As do I. hasField1 is the only method that does not exist/is not accessible, and it is only called
once. What's the problem?
------------------------------------------------------------------------
[2015-03-12 12:21:58] cybermerlin at ya dot ru
But what about question 2)?
I see only hasField1 call
------------------------------------------------------------------------
[2015-03-12 10:52:00] requinix@php.net
get_class_vars() will not show you private variables unless you call it from within their defining
class. While you could call it from within the child in abstract "helper" method, the
parent would still not have access to the variable and would thus error.
On the other hand, protected variables *are* accessible from parents so you could make the variable
protected and the code would work.
------------------------------------------------------------------------
[2015-03-12 06:28:07] cybermerlin at ya dot ru
<?php
abstract class Base{
protected $funcs = [];
public function __call($name, $args) {
error_log("\t>>>Call [$name](". json_encode($args). ") \r\n",3,
LOGFILE);
if (method_exists($this, $name)) {
return call_user_func_array($this->$name, $args);
} else if (isset($this->funcs[ $name ])) {
return call_user_func_array($this->funcs[ $name ], $args);
} else {
throw new Exception("Method <$name> is not accessible.");
}
}
/**
* @param array $args
*
* @example new Base(["field1"=>"value1",
"field2"=>"value2"])
* if u need override __constructor, then use:
* __construct($args){
* ..
* parent::__construct($args);
* }
*/
public function __construct($args = []) {
$nameClass = get_class($this);
#region auto create methods 'hasField' for everyone field\property (if there exists
getter or setter)
$properties = get_class_vars($nameClass);
$keys = array_keys($properties);
foreach ($keys AS $k) {
if ((method_exists($this, "set" . ucfirst($k)) || method_exists($this, "get"
. ucfirst($k)))
&& (!method_exists($this, "has" . ucfirst($k) &&
!isset($this->funcs["has" . ucfirst($k)])))
) {
$v = &$this->$k;
$this->funcs["has" . ucfirst($k)] = function () use (&$v) { return !empty($v);
};
}
}
#endregion
foreach ($args as $k => $v) {
if (property_exists($nameClass, $k)) {
$this->$k = $v;
}
}
}
}
class Test extends Base{
private $field1;
public function setField1($v){$this->field1 = $v;}
public function getField1(){return $this->field1;}
}
$test = new Test();
$test->setField1(23423);
echo $test->hasField1();
?>
------------------------------------------------------------------------
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
https://bugs.php.net/bug.php?id=69220
--
Edit this bug report at https://bugs.php.net/bug.php?id=69220&edit=1