Как переопределить параметр после магического сеттера и геттера в php

Прямо сейчас у меня есть BaseObject, который выполняет ORM для DB. Я полагаюсь на частные $data и магический сеттер и геттер для создания объекта с кучей столбцов в качестве члена частного объекта (динамически). В дочернем классе, если я хочу изменить поведение, чтобы установить отдельный член объекта, я должен переопределить родительский установщик и найти ключ. Мой вопрос в том, есть ли лучший способ сделать это, когда я мог бы просто переопределить один элемент объекта, а не пройти через __setter

Base Object Mapper, который сопоставляется с БД и динамически создает кучу частных параметров

class Base
 {
    private $data = array();

    public function __construct(){
        //get columns info from db and do set
    }
    public function __set($key, $value){
        $this->data[$key] = $value;        
    }

   public function __get($key){
       return isset($this->data[$key])? $this->data[$key] : null;       
   }
}

и дочерний класс. Прямо сейчас, чтобы переопределить настройку параметра, я должен сделать это

 class Child extends Base
 {
     public function __set($name, $value){
        if($name == 'dog' && $value == 'chihuahua')
          $this->dog = 'dog bark wolf wolf';
        else if($name == 'cat' && $value == 'sand')
          $this->cat = 'cat say meow meow';
       ...
     }
 }

мой вопрос, есть ли элегантный способ сделать это, возможно, что-то подобное в дочернем классе?

public function __set_dog($value)
    $this->dog = 'dog bark wolf wolf';

public function __set_cat($value)
   $this->cat = 'cat say meow meow';

цель состоит в том, чтобы сделать

$animal1 = new Animal();
$anmial1->dog = 'pit bull';
$anmial1->cat= 'sand';

$animal2 = new Animal();
$anmial1->dog = 'chihuahua';
$anmial1->cat= 'house cat';

person user332951    schedule 23.10.2012    source источник
comment
Не могли бы вы написать немного больше текста о том, чего вы пытаетесь достичь? Я совершенно не понимаю, что вы пытаетесь сделать.   -  person Jasper    schedule 23.10.2012
comment
Прямо сейчас у меня есть BaseObject, который выполняет ORM для DB. Я полагаюсь на частные $data и магический сеттер и геттер для создания объекта с кучей столбцов в качестве члена частного объекта (динамически). В дочернем классе, если я хочу изменить поведение, чтобы установить отдельный член объекта, я должен переопределить родительский установщик и найти ключ. Мой вопрос в том, есть ли лучший способ сделать это, когда я мог бы просто переопределить один элемент объекта, а не пройти через __setter. заранее спасибо   -  person user332951    schedule 23.10.2012
comment
Если член объекта является закрытым, нет, вы больше ничего не можете сделать.   -  person Winfield Trail    schedule 23.10.2012
comment
В ваших утверждениях if() используется =, когда вы, скорее всего, имеете в виду ==.   -  person nickb    schedule 23.10.2012
comment
nickb, спасибо, что заметил это, я просто пишу код sudo, так что да. Спасибо.   -  person user332951    schedule 24.10.2012


Ответы (1)


Вы можете динамически проверять, существует ли метод получения/установки с условным названием, и вызывать его вместо возврата члена $data. Вот пример:

class Base {
    public function __get($key) {
        if (method_exists($this, $method = 'get' . ucfirst($key))) {
           return $this->$method($key);
        } else {
           return isset($this->data[$key])? $this->data[$key] : null;
        }
    }

    public function __set($key, $value) {
        if (method_exists($this, $method = 'set' . ucfirst($key))) {
           $this->$method($key, $value);
        } else {
           $this->data[$key] = $value;
        }
    }
}

class Animal extends Base {
    protected $data = array('fish' => 'blublublub', 'dog' => 'woof', 'cat' => 'meow');

    public function getDog() {
        return 'dog bark wolf wolf';
    }

    public function getCat() {
        return 'cat say meow meow';
    }
}

$animal = new Animal();
echo $animal->fish; // "blublublub"
echo $animal->dog; // "dog bark wolf wolf"
echo $animal->cat; // "cat say meow meow"
person Jonathan Amend    schedule 23.10.2012