programing

PHP의 정적 속성에 대한 Magic __get getter

nasanasas 2020. 12. 5. 09:54
반응형

PHP의 정적 속성에 대한 Magic __get getter


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 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.");
    }
}

이 시도:

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"

Combining __callStatic and call_user_func or call_user_func_array can give access to static properties in PHP class

Example:

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

참고URL : https://stackoverflow.com/questions/1279382/magic-get-getter-for-static-properties-in-php

반응형