Можно ли изменить методы экземпляра объекта, используя отражение - PullRequest
1 голос
/ 18 ноября 2009

То, что я пытаюсь сделать, - это создать модель предметной области с помощью простого старого объекта PHP. Я создаю библиотеку, которая будет делать все инфраструктурные вещи. Итак, одна из моих моделей выглядит так

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;
  }
}

Теперь, если создаете новый проект и вызываете setType с допустимым объектом Type и сохраняете экземпляр проекта, используя ORM, сохраняются как проект, так и тип. Но затем я загружаю проект и использую метод getType. Я хочу, чтобы ORM прозрачно изменил этот метод, чтобы загрузить объект из настойчивости. Так вот этот метод:

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 для создания класса Proxy для Project с именем Project_Proxy, но иногда встречаются подклассы Project, поэтому я ищу решение, используя Reflection API, если есть способ.

У меня есть поиск в Google, но я не нашел способа изменить поведение метода

Редактировать: или было бы неплохо использовать метод eval Outlet PHP для создания прокси-классов для моих моделей и всех их подклассов?

Ответы [ 2 ]

3 голосов
/ 18 ноября 2009

Нет встроенного способа сделать это. И хотя вы можете сделать это, используя расширение PECL, называемое runkit , я настоятельно рекомендую найти другое решение. Изменение реализации функций, о которых вы не можете знать что-либо, о которых очень опасно и может привести к ошибкам, когда отладка одной такой ошибки может занять больше времени, чем написание операторов if (is_null(... для all ваши функции.

Кстати: не используйте is_null(), так как вы можете получать нулевые значения из базы данных снова и снова. Вы должны хранить извлеченные значения в отдельной переменной.

0 голосов
/ 18 ноября 2009

Глядя на отражение doc на php.net, мне кажется, что невозможно изменить в полете метод.

Вы должны попытаться сделать это по-другому.

...