PHP에서 개체의 보호된 속성을 가져오는 방법
가져오고 설정하려는 보호 속성을 가진 개체가 있습니다.그 물체는 다음과 같이 생겼다.
Fields_Form_Element_Location Object
(
[helper] => formText
[_allowEmpty:protected] => 1
[_autoInsertNotEmptyValidator:protected] => 1
[_belongsTo:protected] =>
[_description:protected] =>
[_disableLoadDefaultDecorators:protected] =>
[_errorMessages:protected] => Array
(
)
[_errors:protected] => Array
(
)
[_isErrorForced:protected] =>
[_label:protected] => Current City
[_value:protected] => 93399
[class] => field_container field_19 option_1 parent_1
)
고고다다 i 를 받고 value
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.$obj->_value
★★★★★★★★★★★★★★★★★」$obj->value
에러가 발생합니다.해 보니, 을 알 수 .PHP Reflection Class
이 PHP 버전입니다5.2.17
그래서 저는 거기서 이 기능을 사용할 수 없습니다.그럼 어떻게 하면 그런 재산을 얻을 수 있을까요?
오류 없이)이 있습니다.ReflectionClass
:
function accessProtected($obj, $prop) {
$reflection = new ReflectionClass($obj);
$property = $reflection->getProperty($prop);
$property->setAccessible(true);
return $property->getValue($obj);
}
5.2로 제한한다고 하셨는데, 2년 전에 5.5가 가장 오래된 지원 버전이기 때문에 최신 버전으로 사람들을 돕고 싶습니다.
는 ( 할 수 된 멤버는 """ (") "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 가 프리픽스 앞에 키가 .chr(0).'*'.chr(0)
(여기서 @fardelian의 코멘트를 참조).이 비초점 기능을 사용하면, 「exposer」를 쓸 수 있습니다.
function getProtectedValue($obj, $name) {
$array = (array)$obj;
$prefix = chr(0).'*'.chr(0);
return $array[$prefix.$name];
}
또는 시리얼라이즈드 스트링에서 값을 해석할 수 있습니다.보호되는 멤버는 같은 프레픽스를 가지고 있는 것 같습니다.
이것은 ReflectionClass의 오버헤드 없이 PHP 5.2에서 작동합니다.그러나 일부 속성이 보호되고 클라이언트 코드에서 숨겨지는 데는 이유가 있습니다.읽기 또는 쓰기로 인해 데이터가 일관되지 않거나 작성자가 인터페이스를 최대한 희박하게 만들기 위해 데이터를 노출할 수 있는 다른 방법을 제공할 수 있습니다.보호된 속성을 직접 읽을 이유가 있을 경우 올바른 접근법은 __get() 매직 메서드를 구현하는 것이므로 항상 해당 메서드가 있는지 확인하고 그 기능을 확인하십시오.이 카운터 직감적인 룩업은 PHP 8.1에서 읽기 전용 속성으로 해결되었습니다.
PHP 8.0에는 ReflectionClass에서 액세스할 수 있는 속성 메타데이터도 있으므로 보호된 멤버로 침입하기 전에 해당 속성도 확인하십시오.속성이 "주석"1을 대체했으므로 해당 특성도 확인하십시오.
1: 주석은 클라이언트 코더에게는 매우 불쾌한 놀람입니다.주석은 코멘트를 해석하여 말도 안 되는 화려한 블랙박스의 쓸모없는 혼란스러운 기능을 추가합니다.이러한 기능은 더 이상 사용하지 않아도 되지만, 아직 존재합니다.
「가시성」의 장에서 설명하고 있듯이, 「보호」의 목적은 다음과 같습니다.
보호되었다고 선언된 구성원은 클래스 자체 내에서만 액세스할 수 있으며 상속된 클래스와 상위 클래스에서만 액세스할 수 있습니다.
외부에서 자산에 액세스해야 하는 경우 다음 중 하나를 선택합니다.
- 보호되고 있다고 선언하지 말고 공개합니다.
- 값을 가져오고 설정하기 위한 몇 가지 함수를 작성합니다(getters 및
원본 클래스를 수정하지 않으려면(혼란시키지 않으려는 타사 라이브러리이므로), 원본 클래스를 확장하는 사용자 정의 클래스를 만듭니다.
class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}
...게터/세터를 추가합니다.
getter와 setter를 추가하지 않고 수업을 수정하고 싶다면...
PHP 7은 closure에 call($obj) 메서드(이전 bindTo보다 빠름)를 추가하여 함수를 호출하여$this
variable은 클래스 내에서와 동일하게 동작합니다(모든 권한을 가집니다).
//test class with restricted properties
class test{
protected $bar="protected bar";
private $foo="private foo";
public function printProperties(){
echo $this->bar."::".$this->foo;
}
}
$testInstance=new test();
//we can change or read the restricted properties by doing this...
$change=function(){
$this->bar="I changed bar";
$this->foo="I changed foo";
};
$change->call($testInstance);
$testInstance->printProperties();
//outputs I changed bar::I changed foo in php 7.0
PHP 7.4+의 경우 Arrow 함수와 를 사용하여 작은 줄 하나만 사용하여 개인 및 보호된 멤버에 액세스할 수 있습니다.
PHP 7.4+
보호된 멤버/개인 멤버 검색 중:
class Test {
protected $data = 'Protected variable!';
}
// Will output "Protected variable!"
echo (fn() => $this->data)->call(new Test);
보호된 멤버/개인 멤버 변경:
class Test {
protected $data = 'Testing';
}
$test = new Test;
(fn() => $this->data = "New Data!")->call($test);
// Will output "New Data!"
echo (fn() => $this->data)->call($test);
물론 여러 멤버를 변경/사용하고 싶다면 일반 기능을 사용할 수 있습니다.
class Test {
protected $data = 'Data!';
}
$test = new Test;
(function() {
$this->new_data = "New {$this->data}";
})->call($test);
// Will output "New Data!"
echo (fn() => $this->new_data)->call($test);
원래 클래스를 변경할 수 없고 확장도 옵션이 아닌 경우 ReflectionProperty 인터페이스를 사용할 수 있습니다.
phptoolcase 라이브러리에는 다음과 같은 편리한 방법이 있습니다.
$value = PtcHandyMan::getProperty($your_object , 'propertyName');
싱글톤 클래스의 스태틱 속성:
$value = PtcHandyMan::getProperty('myCLassName', 'propertyName');
이 툴은 http://phptoolcase.com/guides/ptc-hm-guide.html 에서 찾을 수 있습니다.
저는 외부에서 쓸 수 있는 모든 속성을 공개로 선언하고 싶습니다.외부에서는 표시되지만 쓰기가 불가능한 속성은 protected로 선언하고 읽을 수 있도록 __get() 매직 메서드를 작성해야 합니다.예:
/**
* Class Test
*
* @property int $protected
*
*/
class Test
{
private const READABLE = ['protected'];
protected $protected = 1;
public $public = 2;
public function __get($property)
{
//if you want to read every protected or private
return $this->$property ?? null;
//if you want only some protected and private values to be readable
if (in_array($property, self::READABLE)) {
return $this->$property;
}
}
}
$test = new Test();
echo $test->protected; //outputs 1
echo $test->public; //outputs 2
$test->protected = 3; //outputs error - protected property
가장 좋은 방법은 다음과 같은 속성 선언을 하는 것입니다.
public readonly $protected = 1; //only readable from the outside
public $public = 2; //readable and writable from the outside
그러나 아직 그런 구문은 존재하지 않는다.적어도 나는 그것에 대해 모른다.)P.S. Class DockBlock에서 읽을 수 있는 보호된/개인 속성을 그림과 같이 선언해야 합니다. 그래야 자동 완성할 수 있습니다. 그렇지 않으면 액세스 할 수 있지만 코드를 작성할 때 IDE가 자동 완성 시 이러한 속성을 인식하지 못합니다.
$a=json_encode((array)$obj);
$b=(array)json_decode(str_replace('\u0000*\u0000','',$a));
echo($b['value']);
언급URL : https://stackoverflow.com/questions/20334355/how-to-get-protected-property-of-object-in-php
'programing' 카테고리의 다른 글
외부 키 제약 조건:업데이트 시 및 삭제 시 사용 시기 (0) | 2022.11.23 |
---|---|
페이지 응답성을 높이려면 이벤트 핸들러를 '수동'으로 표시하십시오. (0) | 2022.11.23 |
git repo 브랜치에서 pip install (0) | 2022.11.23 |
stdlib 및 컬러 출력(C) (0) | 2022.11.23 |
Windows에서 동시에 실행되는 여러 Java 버전 (0) | 2022.11.23 |