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

public static function __get($value) 

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

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

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

Цитирование страницы руководства __get :

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

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

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

Может быть, кому-то все еще нужно это:

 static public function __callStatic($method, $args) { if (preg_match('/^([gs]et)([AZ])(.*)$/', $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"); } } 

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

 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, и я хочу, чтобы он сделал определенные предположения о целевом каталоге на основе того, на каком сервере его просят посмотреть. Для этого идеально подходит тонкая версия метода мбзучальского.

 static public function __callStatic($method, $args) { if (preg_match('/^([gs]et)([AZ])(.*)$/', $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."); } } 

Кроме того, вы можете получить статические свойства, получающие доступ к ним как свойства элемента, используя __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" 

попробуй это:

 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);