Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP overriding method of an object

Let's say I have an object of type A, looking like this:

class A{

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


$obj = new A();

is there any way, that without modifying source code of class A I can override method getItem only for object $obj?

if yes, then how?

I tried to do it like in code below:

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

but it returns result of original getItem method twice

The thing I want to achieve is replace method I want only in some objects, don't want to modify base class

@EDIT

I played with code a little bit and found something interesting:

<?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, so something in object has changed, but why it isn't a method? Is it impossible to replace method like that?

like image 352
bestestefan Avatar asked Oct 25 '25 22:10

bestestefan


1 Answers

This is not possible, and luckily so, as it would pose a huge security risk.

Reflection API does allow accessing of methods, but not changing its implemention.

See also
* 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


Update

While you cannot replace the implementiation of a function, you can change the value of a otherwise hidden field using reflection:

<?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
like image 141
maosmurf Avatar answered Oct 27 '25 11:10

maosmurf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!