首页 > 解决方案 > PHP覆盖对象的方法

问题描述

假设我有一个 A 类型的对象,如下所示:

class A{

    private $item;
...
...
...
...
    public function getItem(){
        return $this->item;
    }
}


$obj = new A();

有什么办法,不修改类 AI 的源代码就可以只覆盖getItem对象的方法$obj吗?

如果是,那么如何?

我试着像下面的代码那样做:

class A{

    private $item = 5;
    public function getItem(){
        return $this->item;
    }
}


$obj = new A();

echo $obj->getItem();

$obj->getItem = function(){return 10;};

echo $obj->getItem();

但它两次返回原始方法的结果getItem

我想要实现的是替换我只在某些对象中想要的方法,不想修改基类

@编辑

我玩了一下代码,发现了一些有趣的东西:

<?php

class A{

    private $item = 5;
    public function getItem(){
        return $this->item;
    }
}


$obj = new A();

echo $obj->getItem()."\n";

$obj->getItem = function(){return 10;};

echo $obj->getItem()."\n";

$fun = $obj->getItem;

echo $fun()."\n";

此代码打印 5 5 10,所以对象中的某些内容发生了变化,但为什么它不是方法?这样的方法是不可能的replace吗?

标签: phpoopoverriding

解决方案


这是不可能的,幸运的是,这会带来巨大的安全风险。

反射 API确实允许访问方法,但不会更改其实现。

另请参阅
*是否可以使用反射修改对象实例的方法
* http://www.stubbles.org/archives/65-Extending-objects-with-new-methods-at-runtime.html


更新

虽然您无法替换函数的实现,但您可以使用反射更改隐藏字段的值:

<?php

class A {

  private $item = 5;

  public function getItem() {
    return $this->item;
  }

}

$obj = new A();

$reflect = new ReflectionClass($obj);
$property = $reflect->getProperty('item');
$property->setAccessible(TRUE);
$property->setValue($obj, 10);

echo $obj->getItem(); // 10

推荐阅读