bestestefan
bestestefan

Reputation: 871

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?

Upvotes: 4

Views: 6538

Answers (1)

maosmurf
maosmurf

Reputation: 1946

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

Upvotes: 7

Related Questions