Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/254.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 更改对象结果的方法';s方法_Php_Oop_Decorator - Fatal编程技术网

Php 更改对象结果的方法';s方法

Php 更改对象结果的方法';s方法,php,oop,decorator,Php,Oop,Decorator,我试图找到一种方法来执行一些代码来改变对象方法的结果,而不实际接触对象的代码。我想到的一个方法是使用装饰师: class Decorator { private $object; public function __construct($object) { if (!is_object($object)) { throw new Exception("Not an object"); } $this->

我试图找到一种方法来执行一些代码来改变对象方法的结果,而不实际接触对象的代码。我想到的一个方法是使用装饰师:

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();

这样它可以正常工作,但它有一个缺点,这使得它现在对我来说不可用-它需要将所有行替换为
newtest()
替换为
newdecorator(newtest())
,而这正是我想要避免的-大量干预现有代码。也许我可以在基类中做些什么?

在PHP中不能简单地重载内容。所以你想做的事是做不到的。但事实上,你现在遇到了麻烦,这说明你的设计有缺陷。或者,如果不是你的代码设计,你必须使用的代码(我感觉到你的痛苦)

如果你不能做你想做的事情,那是因为你的代码紧密耦合。也就是说,在类中使用
new
关键字,而不是将它们()注入需要它的类/方法中

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

更新

为了完整性(对于将来可能的读者):如果特定的类已经有了名称空间,并且允许您更改名称空间,那么您可以考虑更改名称空间。然而,这并不是一个很好的实践,因为它可能会与自动加载器等发生冲突。这方面的一个例子是。但考虑到你不能这样做,我不认为这是可能的,你想要什么。另外,你不应该真正使用这个“解决方案”

更新2

看起来在某个时候(很久以前)有一些过载扩展,但我唯一关心的是。不管怎样,不要指望它现在还能工作PHP中根本没有真正的重载

发现了一些东西(一个死掉的项目,不再工作,导致类重载):


可能是另一个项目(当然也死了):

我不是一个PHP程序员,但我认为这正是您所寻找的。您可以尝试一些框架,例如本文中列出的框架。

来自:

  • 将原始的“Decorator”类子类化为“Component”类

  • 因此,我认为您应该将要修饰的类保持为私有的,并且只公开已经修饰过的类。

    如果
    Test
    扩展了定义了
    \u调用的类,它的工作方式是否相同?你可以试着这么做……好吧,你的答案中唯一错误的地方是假设我的设计和代码:)。否则我完全同意。顺便问一下,类是否有名称空间,是否允许更改名称空间?