Нужно ли перегруженному __get управлять всеми переменными-членами? - PullRequest
1 голос
/ 22 мая 2009

Я создаю функцию __get () для класса, чтобы контролировать доступ к моим закрытым переменным-членам. Нужно ли разрабатывать функцию для обработки всех возможных значений значений элементов или я не могу писать ее для открытых элементов? Также я предполагаю, что классы, которые наследуют этот класс, будут использовать мою функцию __get () для доступа к закрытым членам.

class ClassA{
  private $collection = array();
  public $value;

  function __get($item){
    return $collection[$item];
  }

Ответы [ 3 ]

1 голос
/ 22 мая 2009

Нет, нет.


class A {
   public $foo = 'bar';
   private $private = array();

   public function __get($key) {
      echo 'Called __get() at line #' ,__LINE__, ' with key {', $key ,'}',"\n";
      return $this->private[$key];
   }

   public function __set($key, $val) {
      $this->private[$key] = $val;
   }
}


$a = new A();

var_dump($a->foo);
$a->bar = 'baz';
var_dump($a->bar);

И да, это будет:


class B extends A { private $private = array(); }
$b = new B();
var_dump($b->bar);
0 голосов
/ 22 мая 2009

Прежде всего PHP ищет имя свойства в определении класса и пытается вернуть его значение. Если свойства нет - PHP пытается вызвать __get ($ var), и здесь вы можете вернуть все, что захотите. Это немного сбивает с толку поведение тех, кто знает Java-подобные методы получения / установки, где вы должны определить их для каждого члена класса, к которому вы хотите получить доступ.

Когда удобно использовать Java-подобные методы получения / установки - вы можете написать что-то вроде этого:

public function __set($var, $value)
{
    if (method_exists($this, $method = "_set_" . $var))
    {
        call_user_func(array($this, $method), $value);
    }
}
public function __get($var)
{
    if (method_exists($this, $method = "_get_" . $var))
    {
        return call_user_func(array($this, $method), $value);
    }
}

, а затем используйте этот код, определив пользовательские методы получения / установки

protected function _get_myValue() 
     {
         return $this->_myValue; 
     }
protected function _set_myValue($value)
{
    $this->_myValue = $value;
}

и доступ к определенным методам следующим образом:

$obj->myValue = 'Hello world!';
0 голосов
/ 22 мая 2009

Что ж, ваш код потерпит неудачу с частными элементами, не установленными в вашем массиве. Но опять же, вы можете использовать это как способ обработки того, что входит и выходит из вашего массива, как таковое;

  function __get($item){
    if ( isset ( $collection[$item] ) )
       return $collection[$item];
    else {
       try {
          return $this->$item ;  // Dynamically try public values
       } catch (Exception $e) {
          $collection[$item] = 0 ; // Make it exist
       }
    }
  }

Классы, которые наследуют ваши вызовы, будут использовать эту __get (), но могут быть переопределены, поэтому для простоты используйте parent :: __ construct (). Также обратите внимание, что они не могут быть статичными. Дальнейшее чтение .

...