是否可以使用反射修改对象实例的方法 [英] Is it possible to modify methods of an object instance using reflection

查看:18
本文介绍了是否可以使用反射修改对象实例的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要做的是用一个普通的旧 PHP 对象创建一个域模型.我正在创建一个库,它将完成所有基础设施的工作.所以我的一个模型看起来像这样

What I'm trying to do is create a domain model with a Plain Old PHP Object. The I'm creating a library which will do all the infrastructure stuff. So one of my models looks like this

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 透明地修改了这个方法以从持久性加载对象.所以这个方法在这里:

Now if create a new Project and call setType with a valid Type object and save the project instance using the ORM both the project and type is saved. But then I load the Project and use getType method I want the ORM to have modified this method transparently to load the object from persitence. So this method here:

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 的代理类,但有时会有 Project 的子类,所以如果有办法,我正在使用 Reflection API 寻找解决方案.

Outlet PHP uses eval to create a Proxy class for Project called Project_Proxy but sometimes there will be subclasses of Project so I am searching for a solution by using Reflection API if there is a way.

我在谷歌上搜索过,但还没有找到改变方法行为的方法

I have search google but haven't found anyway to change a method behaviour

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

or would it be a good idea to use Outlet PHP's eval method to create Proxy Classes for my models and all subclasses of them?

推荐答案

没有内置的方法可以做到这一点.尽管您可以使用 PECL 扩展名为 runkit 来做到这一点,但我强烈建议您找到另一种解决方案.更改您不知道任何 的函数的实现是非常危险的,并且可能导致错误,在这种情况下,调试单个此类错误可能比编写 if (is_null(...<用于所有函数的/code> 语句.

There is no builtin way of doing this. And although you can do that using the PECL extension called runkit, I would strongly recommend finding another solution. Changing the implementation of functions you can't know anything about is very dangerous and might lead to bugs where debugging a single such bug can take longer than writing the if (is_null(... statements for all your functions.

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

BTW: don't use is_null(), since you might fetch null values from the database over and over again. You should store the fetched values in a separate variable.

这篇关于是否可以使用反射修改对象实例的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆