PHP подход к магии питона __getattr __ () - PullRequest
4 голосов
/ 05 января 2012

Мне было интересно, есть ли какой-нибудь способ в PHP дублировать некоторые магические возможности доступа к атрибутам / ключам Python.

Я использую класс Mongo ORM, написанный Стивом Лейси под названием Minimongo , в котором он использует __getattr__ и __getitem__ для перенаправления ключа и атрибутного доступа и сохранения Документно-ориентированный характер Монго. val = doc.foo и val = doc['foo'] становятся эквивалентными.

Мне было интересно, есть ли в PHP аналогичный интерфейс, который позволял бы изменять способ обработки доступа к объекту для класса, который наследуется от него. Я просмотрел STL и не смог найти тот, который заполнил костюм. Это было бы очень полезно для установки значений по умолчанию. Спасибо.

Ответы [ 2 ]

9 голосов
/ 05 января 2012

Посмотрите на __ get () и __set () и ArrayAccess .

С первым вы можете сделать доступ к закрытым членам, как в $obj->foo, с последним вы можете получить к ним доступ как $obj['foo'].

Вы можете встроить их, как захотите, изнутри.

Лично я бы посоветовал вам сохранить эти магически доступные свойства в одномчлен одного массива класса, так что вы не получите спагетти-код.

POC:

 1  <?php
 2  class Magic implements ArrayAccess {
 3  
 4      protected $items = array();
 5  
 6      public function offsetExists($key) {
 7          return isset($this->items[$key]);
 8      }
 9      public function offsetGet($key) {
10          return $this->items[$key];
11      }
12      public function offsetSet($key, $value) {
13          $this->items[$key] = $value;
14      }
15      public function offsetUnset($key) {
16          unset($this->items[$key]);
17      }
18  
19      //do not modify below, this makes sure we have a consistent
20      //implementation only by using ArrayAccess-specific methods
21      public function __get($key) {
22          return $this->offsetGet($key);
23      }
24      public function __set($key, $value) {
25          $this->offsetSet($key, $value);
26      }
27      public function __isset($key) {
28          return $this->offsetExists($key);
29      }
30      public function __unset($key) {
31          $this->offsetUnset($key);
32      }
33  }
34  
35  //demonstrate the rountrip of magic
36  $foo = new Magic;
37  $foo['bar'] = 42;
38  echo $foo->bar, PHP_EOL;//output 42
39  $foo->bar++;
40  echo $foo['bar'];//output 43
41  

Согласованность, Милорд, в точности, как вы просили.

2 голосов
/ 05 января 2012

Вам стоит взглянуть на магические методы PHP: http://php.net/manual/en/language.oop5.magic.php

__get(), __set() и __call() могут делать то, что вы хотите.

...