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 메서드만 사용하는 정책을 채택하는 것이 가장 좋습니다.
PHP 8.1 이후 네이티브 읽기 전용 속성이 구현되었습니다.
속성을 선언하는 동안 읽기 전용 속성을 한 번만 초기화할 수 있습니다.
class Test {
public readonly string $prop;
public function __construct(string $prop) {
$this->prop = $prop;
}
}
--
class Test {
public function __construct(
public readonly string $prop,
) {}
}
읽기 전용 속성을 수정하려고 하면 다음 오류가 발생합니다.
Error: Cannot modify readonly property Test::$prop
PHP 8.2 업데이트
PHP 8.2 이후로 다음과 같이 정의할 수 있습니다.readonly
반 전체
readonly class Test {
public string $prop;
public function __construct(string $prop) {
$this->prop = $prop;
}
}
그러나 __get()을 사용하여 노출된 개인 속성은 개체의 구성원을 열거하는 함수(예: json_encode())에서는 볼 수 없습니다.
데이터베이스에서 많은 데이터가 채워지는 복잡한 구조를 전달하는 것이 좋은 방법인 것 같아 json_encode()를 사용하여 정기적으로 자바스크립트에 PHP 객체를 전달합니다.이 데이터가 이를 사용하는 자바스크립트에 채워지도록 개체에 공용 속성을 사용해야 하지만, 이는 해당 속성이 공용이어야 한다는 것을 의미합니다(따라서 동일한 파장에 있지 않은 다른 프로그래머(또는 나쁜 밤 이후에 자신)가 해당 속성을 직접 수정할 위험이 있음).비공개로 설정하고 __get() 및 __set()을 사용하면 json_encode()가 보이지 않습니다.
"읽기 전용" 접근성 키워드가 있으면 좋지 않을까요?
다음은 클래스의 모든 속성을 외부에서 읽기 전용으로 렌더링하는 방법이며 상속된 클래스에는 쓰기 권한이 있습니다;-).
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에서 테스트됨
이미 답을 얻으셨지만 아직도 찾고 계신 분들께:
모든 "read only" 변수를 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()가 있는 배열을 사용합니다.
직렬화를 위해 개인/보호된 속성을 노출하는 방법을 찾고 있는 사람의 경우 getter 메서드를 사용하여 읽기 전용으로 만들 수 있도록 선택한 경우 다음과 같은 방법이 있습니다(@Matt: 예를 들어 json의 경우).
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');
}
}
}
값()을 읽기 전용으로 설정하려면 속성을 가져오거나 설정하는 방법입니다.그러면 그냥 다음과 같은 작업을 수행하게 됩니다.
return $this->m_value;
지금 당장 Value() 함수를 얻거나 설정할 수 있습니다.
언급URL : https://stackoverflow.com/questions/402215/php-readonly-properties
'sourcecode' 카테고리의 다른 글
NodeJS: 서버의 포트를 가져오는 방법은 무엇입니까? (0) | 2023.10.10 |
---|---|
결측값이 있는 열의 부분 집합에 대한 행 단위 평균 (0) | 2023.10.10 |
mysql 결과에서 제외할 사용자 호스트 쌍 제공 (0) | 2023.10.10 |
보기 호출기 내부의 조각 바꾸기 (0) | 2023.10.10 |
이 Oracle ORA-01403을 처리하는 올바른 방법은 무엇입니까? 데이터를 찾을 수 없음 예외? (0) | 2023.10.10 |