Подтвердить что ты не робот

Magic __get getter для статических свойств в PHP

public static function __get($value)

не работает, и даже если это так, так бывает, что мне уже нужен магический __get getter, например, свойства в том же классе.

Возможно, это вопрос "да" или "нет", так что это возможно?

4b9b3361

Ответ 1

Нет, это невозможно.

Цитата справочная страница __get:

Перегрузка участника работает только в контекст объекта. Эти магические методы не будет срабатывать при статическом контекст. Поэтому эти методы могут не объявляется статическим.


В PHP 5.3 добавлен __callStatic; но пока нет __getStatic и __setStatic; даже если идея иметь/кодировать их часто возвращается на php internals @mailling-list.

Существует даже Запрос комментариев: Статические классы для PHP
Но, все же, не реализовано (еще?)

Ответ 2

Возможно, кому-то это еще нужно:

static public function __callStatic($method, $args) {

  if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
    $reflector = new \ReflectionClass(__CLASS__);
    $property = strtolower($match[2]). $match[3];
    if ($reflector->hasProperty($property)) {
      $property = $reflector->getProperty($property);
      switch($match[1]) {
        case 'get': return $property->getValue();
        case 'set': return $property->setValue($args[0]);
      }     
    } else throw new InvalidArgumentException("Property {$property} doesn't exist");
  }
}

Ответ 3

Очень приятный мбзучальски. Но, похоже, он работает только с общественными переменными. Просто измените свой переключатель на это, чтобы он мог получить доступ к частным/защищенным:

switch($match[1]) {
   case 'get': return self::${$property->name};
   case 'set': return self::${$property->name} = $args[0];
}

И вы, вероятно, захотите изменить оператор if, чтобы ограничить доступные переменные, иначе это приведет к тому, что они будут закрыты или защищены.

if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)

Так, например, у меня есть класс, предназначенный для вывода различных данных для меня из удаленного сервера с использованием модуля ssh pear, и я хочу, чтобы он сделал определенные предположения о целевом каталоге на основе того, на каком сервере его попросили посмотреть в. Для этого идеально подходит тонкая версия метода mbrzuchalski.

static public function __callStatic($method, $args) {
    if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
        $reflector = new \ReflectionClass(__CLASS__);
        $property = strtolower($match[2]). $match[3];
        if ($reflector->hasProperty($property)) {
            if ($property == "server") {
                $property = $reflector->getProperty($property);
                switch($match[1]) {
                    case 'set':
                        self::${$property->name} = $args[0];
                        if ($args[0] == "server1") self::$targetDir = "/mnt/source/";
                        elseif($args[0] == "server2") self::$targetDir = "/source/";
                        else self::$targetDir = "/";
                    case 'get': return self::${$property->name};
                }
            } else throw new InvalidArgumentException("Property {$property} is not publicly accessible.");
        } else throw new InvalidArgumentException("Property {$property} doesn't exist.");
    }
}

Ответ 4

Кроме того, вы можете получить статические свойства, доступ к ним как свойства элемента, используя __get():

class ClassName {

static $data = 'smth';

function __get($field){
       if (isset($this->$field)){
          return $this->$field;
        }
        if(isset(self::$$field)){  
          return self::$$field;  // here you can get value of static property
        }
        return NULL;
      }
}

$obj = new ClassName();
echo $obj->data; // "smth"

Ответ 5

попробуйте следующее:

class nameClass{
    private static $_sData = [];
    private static $object = null;
    private $_oData = [];

    public function __construct($data=[]){
        $this->_oData = $data;
    }

    public static function setData($data=[]){
        self::$_sData = $data;
    }

    public static function Data(){
        if( empty( self::$object ) ){
            self::$object = new self( self::$_sData ); 
        }
        return self::$object;
    }

    public function __get($key) {
        if( isset($this->_oData[$key] ){
            return $this->_oData[$key];
        }
    }

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

nameClass::setData([
    'data1'=>'val1',
    'data2'=>'val2',
    'data3'=>'val3',
    'datan'=>'valn'
]);

nameClass::Data()->data1 = 'newValue';
echo(nameClass::Data()->data1);
echo(nameClass::Data()->data2);