programing

PHP에서 개체의 보호된 속성을 가져오는 방법

coolbiz 2022. 11. 23. 21:13
반응형

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보다 빠름)를 추가하여 함수를 호출하여$thisvariable은 클래스 내에서와 동일하게 동작합니다(모든 권한을 가집니다).

 //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

반응형