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