Magic __ Php의 정적 특성에 대한 getter
-
16-09-2019 - |
문제
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)([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");
}
}
아주 좋은 mbrzuchalski. 그러나 그것은 공개 변수에만 작동하는 것 같습니다. 개인/보호 된 제품에 액세스 할 수 있도록 스위치를 변경하기 만하면됩니다.
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 배 모듈을 사용하여 원격 서버에서 다양한 데이터를 가져 오도록 설계된 클래스가 있으며, 어떤 서버를보고 싶은지에 따라 대상 디렉토리에 대해 특정 가정을 만들고 싶습니다. 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.");
}
}
이 시도:
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);
또한 __get ()를 사용하여 멤버 속성과 같은 정적 속성에 액세스 할 수 있습니다.
class ClassName {
private 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"
결합 __callStatic
그리고 call_user_func
또는 call_user_func_array
PHP 클래스에서 정적 특성에 액세스 할 수 있습니다
예시:
class myClass {
private static $instance;
public function __construct() {
if (!self::$instance) {
self::$instance = $this;
}
return self::$instance;
}
public static function __callStatic($method, $args) {
if (!self::$instance) {
new self();
}
if (substr($method, 0, 1) == '$') {
$method = substr($method, 1);
}
if ($method == 'instance') {
return self::$instance;
} elseif ($method == 'not_exist') {
echo "Not implemented\n";
}
}
public function myFunc() {
echo "myFunc()\n";
}
}
// Getting $instance
$instance = call_user_func('myClass::$instance');
$instance->myFunc();
// Access to undeclared
call_user_func('myClass::$not_exist');