gpt4 book ai didi

php - 改变对象方法结果的方法

转载 作者:行者123 更新时间:2023-12-04 05:16:47 26 4
gpt4 key购买 nike

我试图找到一种方法来执行一些代码来更改对象方​​法的结果,而无需实际接触对象的代码。我想出的一种方法是使用装饰器:

class Decorator {
private $object;

public function __construct($object) {
if (!is_object($object)) {
throw new Exception("Not an object");
}
$this->object = $object;
}

protected function doSomething(&$val) {
$val .= "!!";
}

public function __call($name, $arguments) {
$retVal = call_user_func_array(array($this->object, $name), $arguments);
$this->doSomething($retVal);
return $retVal;
}
}

class Test extends BaseTest {
public function run() {
return "Test->run()";
}
}

$o = new Decorator(new Test());
$o->run();

这样它就可以正常工作,但它有一个缺点,它现在对我来说无法使用 - 它需要用 new Test() 替换所有行与 new Decorator(new Test())这正是我想要避免的——大量干预现有代码。也许我可以在基类中做些什么?

最佳答案

一个不是简单地重载 PHP 中的东西。所以你想做的事是做不到的。但是你现在遇到麻烦的事实是一个很大的说明你的设计是有缺陷的。或者,如果不是您的代码设计,您必须使用的代码(我感到您的痛苦)。

如果你不能做你想做的事,那是因为你的代码紧密耦合了。 IE。您使用 new类中的关键字,而不是将它们 ( dependency injection ) 注入(inject)到需要它的类/方法中。

除了不能轻松地交换类之外,由于紧密耦合,您还可以轻松地测试您的单元。

更新

为了完整性(对于 future 可能的读者):如果特定类已经被命名空间并且您被允许更改命名空间,那么您可以考虑更改命名空间。然而,这并不是一个很好的做法,因为它可能会与例如自动加载器一起使用。这方面的一个例子是 PSR-0 .但是考虑到你不能这样做,我看不出你想要什么。附言你不应该真正使用这个“解决方案”。

更新2

似乎在某个时间(很早以前)出现了一些过载扩展,但我唯一的事情是 have found关于它是some bug report .不要指望它现在仍然有效。 ;-) PHP 中根本没有真正的重载。

找到了一些东西(一个不再工作的死项目,它启用了类重载):http://pecl.php.net/package/runkit

可能是另一个项目(当然也死了):http://pecl.php.net/package/apd

关于php - 改变对象方法结果的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14154245/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com