programing tip

PHP 읽기 전용 속성?

itbloger 2020. 12. 13. 09:02
반응형

PHP 읽기 전용 속성?


PHP의 DOM 클래스 (DOMNode, DOMEElement 등)를 사용하면서 실제로 읽기 전용 속성을 가지고 있음을 알았습니다. 예를 들어 DOMNode의 $ nodeName 속성을 읽을 수 있지만 여기에 쓸 수는 없습니다 (PHP를 수행하면 치명적인 오류가 발생 함).

PHP에서 내 자신의 읽기 전용 속성을 어떻게 만들 수 있습니까?


다음과 같이 할 수 있습니다.

class Example {
    private $__readOnly = 'hello world';
    function __get($name) {
        if($name === 'readOnly')
            return $this->__readOnly;
        user_error("Invalid property: " . __CLASS__ . "->$name");
    }
    function __set($name, $value) {
        user_error("Can't set property: " . __CLASS__ . "->$name");
    }
}

정말 필요할 때만 사용하세요. 일반 속성 액세스보다 느립니다. PHP의 경우 외부에서 속성을 변경하기 위해 setter 메서드 만 사용하는 정책을 채택하는 것이 가장 좋습니다.


그러나 __get () 만 사용하여 노출 된 개인 속성은 객체의 멤버를 열거하는 함수 (예 : json_encode ())에는 표시되지 않습니다.

json_encode ()를 사용하여 PHP 객체를 Javascript에 정기적으로 전달합니다. 데이터베이스에서 많은 양의 데이터가 채워진 복잡한 구조를 전달하는 좋은 방법 인 것 같습니다. 이 데이터가이를 사용하는 자바 스크립트를 통해 채워지도록 이러한 개체에서 공용 속성을 사용해야하지만 이는 해당 속성이 공용이어야 함을 의미합니다 (따라서 다른 프로그래머가 동일한 파장에 있지 않을 위험이 있습니다 (또는 아마도 나쁜 밤을 보낸 후) 직접 수정할 수 있습니다.) 비공개로 설정하고 __get () 및 __set ()을 사용하면 json_encode ()에서 볼 수 없습니다.

"읽기 전용"접근성 키워드가 있으면 좋지 않을까요?


나는 당신이 이미 당신의 대답을 얻었지만 여전히 찾고있는 사람들을 위해 :

모든 "readonly"변수를 private 또는 protected로 선언하고 다음과 같이 매직 메서드 __get ()을 사용하십시오.

/**
 * This is used to fetch readonly variables, you can not read the registry
 * instance reference through here.
 * 
 * @param string $var
 * @return bool|string|array
 */
public function __get ($var)
{
    return ($var != "instance" && isset($this->$var)) ? $this->$var : false;
}

보시다시피이 메서드는 사용자가 선언 된 모든 변수를 읽을 수 있도록 허용하므로 $ this-> instance 변수도 보호했습니다. 여러 변수를 차단하려면 in_array ()와 함께 배열을 사용하십시오.


다음은 클래스의 모든 속성을 외부에서 read_only로 렌더링하는 방법입니다. 상속 된 클래스에는 쓰기 권한이 있습니다 ;-).

class Test {
    protected $foo;
    protected $bar;

    public function __construct($foo, $bar) {
        $this->foo = $foo;
        $this->bar = $bar;
    }

/**
 * All property accessible from outside but readonly
 * if property does not exist return null
 *
 * @param string $name
 *
 * @return mixed|null
 */
    public function __get ($name) {
        return $this->$name ?? null;
    }

/**
 * __set trap, property not writeable
 *
 * @param string $name
 * @param mixed $value
 *
 * @return mixed
 */
    function __set ($name, $value) {
        return $value;
    }
}

php7에서 테스트


직렬화를 위해 개인 / 보호 된 속성을 노출하는 방법을 찾고있는 사람들을 위해 getter 메서드를 사용하여 읽기 전용으로 설정하는 경우 다음 방법이 있습니다 (예 : json의 경우 @Matt :).

interface json_serialize {
    public function json_encode( $asJson = true );
    public function json_decode( $value );
}

class test implements json_serialize {
    public $obj = null;
    protected $num = 123;
    protected $string = 'string';
    protected $vars = array( 'array', 'array' );
    // getter
    public function __get( $name ) {
        return( $this->$name );
    }
    // json_decode
    public function json_encode( $asJson = true ) {
        $result = array();
        foreach( $this as $key => $value )
            if( is_object( $value ) ) {
                if( $value instanceof json_serialize )
                    $result[$key] = $value->json_encode( false );
                else
                    trigger_error( 'Object not encoded: ' . get_class( $this ).'::'.$key, E_USER_WARNING );
            } else
                $result[$key] = $value;
        return( $asJson ? json_encode( $result ) : $result );
    }
    // json_encode
    public function json_decode( $value ) {
        $json = json_decode( $value, true );
        foreach( $json as $key => $value ) {
            // recursively loop through each variable reset them
        }
    }
}
$test = new test();
$test->obj = new test();
echo $test->string;
echo $test->json_encode();

Class PropertyExample {

        private $m_value;

        public function Value() {
            $args = func_get_args();
            return $this->getSet($this->m_value, $args);
        }

        protected function _getSet(&$property, $args){
            switch (sizeOf($args)){
                case 0:
                    return $property;
                case 1:
                    $property = $args[0];
                    break;  
                default:
                    $backtrace = debug_backtrace();
                    throw new Exception($backtrace[2]['function'] . ' accepts either 0 or 1 parameters');
            }
        }


}

이것이 Value ()를 읽기 전용으로 만들고 싶다면 속성을 가져 오거나 설정하는 방법입니다. 대신 다음을 수행하십시오.

    return $this->m_value;

현재 Value () 함수가 가져 오거나 설정되는 위치입니다.

참고 URL : https://stackoverflow.com/questions/402215/php-readonly-properties

반응형