代码之家  ›  专栏  ›  技术社区  ›  bestestefan

对象的php重写方法

  •  0
  • bestestefan  · 技术社区  · 8 年前

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

    class A{
    
        private $item;
    ...
    ...
    ...
    ...
        public function getItem(){
            return $this->item;
        }
    }
    
    
    $obj = new A();
    

    有没有办法,在不修改A级源代码的情况下 重写方法 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();
    

    但是 it returns 原始结果 获取项目 方法两次

    我想实现的是 代替 方法,我只想在一些对象中使用,不想修改基类

    @编辑

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

    <?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 prints 5 5 10 ,所以对象中的某些内容已更改,但为什么它不是方法?不可能吗 replace 这样的方法?

    1 回复  |  直到 8 年前
        1
  •  1
  •   maosmurf    8 年前

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

    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
    
    推荐文章