在php中的std对象中添加方法

tpgth1q7  于 2023-01-19  发布在  PHP
关注(0)|答案(5)|浏览(117)

是否可以通过这种方式添加方法/函数,例如

$arr = array(
    "nid"=> 20,
    "title" => "Something",
    "value" => "Something else",
    "my_method" => function($arg){....}
);

或者像这样

$node = (object) $arr;
$node->my_method=function($arg){...};

如果可能的话,我该如何使用这个函数/方法呢?

s2j5cfk0

s2j5cfk01#

现在可以在PHP 7.1中使用匿名类实现这一点

$node = new class {
    public $property;

    public function myMethod($arg) { 
        ...
    }
};

// and access them,
$node->property;
$node->myMethod('arg');
zf9nrax1

zf9nrax12#

你不能动态地添加一个方法到stdClass并以正常的方式执行它。但是,你可以做一些事情。
在第一个示例中,我们创建了一个closure,可以通过发出以下命令来执行闭包:

$arr['my_method']('Argument')

你可以创建一个stdClass对象并为其属性之一分配一个闭包,但是由于语法冲突,你不能直接执行它,而是必须执行如下操作:

$node = new stdClass();
$node->method = function($arg) { ... }
$func = $node->method;
$func('Argument');

尝试

$node->method('Argument')

将生成错误,因为stdClass上不存在方法“method”。
请参阅SO answer,了解使用神奇的方法__call的一些巧妙的黑客手法。

ssm49v7z

ssm49v7z3#

从PHP 7开始,也可以直接调用匿名函数属性:

$obj = new stdClass;
$obj->printMessage = function($message) { echo $message . "\n"; };
echo ($obj->printMessage)('Hello World'); // Hello World

这里表达式$obj->printMessage产生匿名函数,然后直接用参数'Hello World'执行。但是在调用函数表达式之前,必须将其放入paranetheses中,这样以下操作仍然会失败:

echo $obj->printMessage('Hello World'); 
// Fatal error: Uncaught Error: Call to undefined method stdClass::printMessage()
kpbwa7wx

kpbwa7wx4#

另一个解决方案是创建一个匿名类,并通过神奇的函数__call代理调用,使用arrow函数,您甚至可以保持对上下文变量的引用:

new Class ((new ReflectionClass("MyClass"))->getProperty("myProperty")) {
            public function __construct(ReflectionProperty $ref)
            {
                $this->setAccessible = fn($o) => $ref->setAccessible($o);
                $this->isInitialized = fn($o) => $ref->isInitialized($o);
                $this->getValue = fn($o) => $ref->getValue($o);
            }

            public function __call($name, $arguments)
            {
                $fn = $this->$name;
                return $fn(...$arguments);
            }

    }
vsaztqbk

vsaztqbk5#

class myclass {
function __call($method, $args) {
if (isset($this->$method)) {
$func = $this->$method;
return call_user_func_array($func, $args);
}
}
}
$obj = new myclass();
 $obj->method = function($var) { echo $var; };

$obj->method('a');

或者你可以创建一个默认的类并使用...

相关问题