是否可以使用反射修改对象实例的方法

时间:2009-11-18 06:38:54

标签: php reflection orm domain-model

我要做的是使用Plain Old PHP Object创建域模型。 我正在创建一个可以完成所有基础设施工作的库。 所以我的一个模型看起来像这样

class Project {
  public $id;
  public $name;
  public $typeId;

  private $type;

  public function getType() {
    return $this->type;
  }

  public function setType(Type $type) {
    $this->typeId = $type->id;
    $this->type = $type;
  }
}

现在,如果创建一个新项目并使用有效的Type对象调用setType并使用ORM保存项目实例,则保存项目和类型。但后来我加载项目并使用getType方法我希望ORM透明地修改此方法以从persitence加载对象。所以这个方法在这里:

public function getType() {
  return $this->type;
}

透明地改为:

public function getType() {
  if (is_null($this->type) {
    $this->type = $this->adapter->findById('table', $this->typeId);
  }

  return $this->type; // or return parent::getType();
}

Outlet PHP使用eval为Project创建一个名为Project_Proxy的Proxy类,但有时会有Project的子类,所以如果有办法,我会使用Reflection API搜索解决方案。

我有搜索谷歌,但无论如何都没有找到改变方法行为

编辑:或者使用Outlet PHP的eval方法为我的模型及其所有子类创建代理类是否是一个好主意?

2 个答案:

答案 0 :(得分:3)

没有内置的方法可以做到这一点。虽然你可以使用PECL extension called runkit来做到这一点,但我强烈建议你找另一个解决方案。更改您无法知道任何的函数的实现是非常危险的,并且可能导致调试单个此类错误所花费的时间比编写所有if (is_null(...语句所需的时间更长的错误你的职能。

顺便说一句:不要使用is_null(),因为您可能会一遍又一遍地从数据库中获取空值。您应该将获取的值存储在单独的变量中。

答案 1 :(得分:0)

看看php.net上的反射doc,在我看来,在飞行中修改方法是不可能的。

你应该尝试以不同的方式做到这一点。