Защищать свойство объекта, не зная его имени заранее - PullRequest
0 голосов
/ 18 сентября 2010

Это может быть невозможно, но я решил спросить, прежде чем переделывать все это ...:

У меня есть объектный класс, который может получать "кусочки", которые также являются объектами.Это работает в основном так:

class myObject {
    //Receives an associative array of "Piece" objects
    function __construct($objects) {
        foreach( $objects as $k=>$v ) {
            $this->{$k} = $v;
        }
    }
}

Я опускаю много кода, очевидно, но я надеюсь, что это дает вам идею.По сути, у меня есть множество различных «кусочных» объектов, которые делают разные вещи, и если я передам их массив в myObject, тогда myObject станет очень гибким и полезным классом для выполнения самых разных задач.

Итак, я мог бы использовать это для создания Book объекта и иметь фрагменты, которые включали бы «Часть автора» и «Часть ISBN», и эти части знали бы, как проверять данные и т. Д. Так что я мог бы иметь $book с объектами, установленными в переменные-члены author и isbn.

Это здорово, потому что я могу делать такие вещи, как:

echo $book->author; //all Pieces have a __toString() method.
echo $book->author->firstName;
$book->author->showBio();
$book->author->contactForm();

… и т. д.

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

Но проблема в том,Я не хочу, чтобы кто-то еще мог использовать код позже, чтобы попытаться:

$book->author = "John Doe";

… потому что тогда у них было бы просто значение вместо объекта author.Я хотел бы, чтобы это дало им ошибку и проинструктировало их сделать это вместо этого:

$book->author->setName("John Doe");

Так как я заранее не знаю, какие части могут быть в каком-либо отдельном объекте (и весь смыслчтобы иметь возможность мгновенно собирать любые объекты), я не могу просто установить private $author в объявлении класса.

Я попытался немного пошутить с __get() и __set(), но я не мог заставить его работать, не ставя под угрозу функциональность объектов, как они есть сейчас.

Итак, как я уже сказал, я знаю, что это может быть невозможно, но прежде чем сдаться, я подумал, чтоспросил бы.Есть ли способ защитить свойство объекта после его создания без объявления его в определении класса?

1 Ответ

3 голосов
/ 18 сентября 2010

Это абсолютно не невозможно. Вы должны перезаписать магические функции __ get и __set

Как это:

class myObject {
  protected $data = array();

  public function __construct($objects) {
    foreach( $objects as $k=>$v ) {
      $this->data[$k] = $v;
    }
  }

  /* your code */

  public function __get($name) {
    if(array_key_exists($name, $this->data)) {
      return $this->data[$name];
    }
    return null;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...