【问题标题】:PHP overriding method of an objectPHP覆盖对象的方法
【发布时间】:2018-07-18 18:48:57
【问题描述】:

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

class A{

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


$obj = new A();

有没有什么方法可以在不修改 A 类源代码的情况下只为对象 $obj 覆盖方法 getItem

如果是,那么如何?

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

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

但是it returns 原始getItem 方法的结果两次

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

@编辑

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

<?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";

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

【问题讨论】:

  • 子类呢?
  • 这是code smell。如果您希望对象表现不同,那么您应该有不同的对象。
  • @AlexHowansky 问题是我只需要在一个代码位置执行此操作,我认为这是实现它的最简单方法
  • @alanfcm 是的,我想到了,但我必须在项目中只做一次,所以我想到它只是因为我很好奇它是否可以这样工作,是否可以覆盖方法像这样
  • class B extends A { private $item = 'something else'; public function getItem(){ return $this-&gt;item; }} 然后$object = new B;

标签: php oop overriding


【解决方案1】:

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

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

另见
* Is it possible to modify methods of an object instance using reflection
* 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

【讨论】:

    猜你喜欢
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 2012-12-03
    相关资源
    最近更新 更多