web-dev-qa-db-ja.com

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
)

オブジェクトのvalueプロパティを取得したい。 $obj->_valueまたは$obj->valueを試すと、エラーが発生します。 PHP Reflection Classを使用するソリューションを検索して見つけました。それは私のローカルで動作しましたが、サーバーでPHPバージョンは5.2.17ですので、そこでこの関数を使用することはできません。

49
Awais Qarni

Visibility の章で説明されているように、それが「保護」の意味です。

Protectedと宣言されたメンバーは、クラス自体内でのみ継承され、親クラスからアクセスできます。

外部からプロパティにアクセスする必要がある場合は、いずれかを選択してください。

  • 保護されていると宣言せず、代わりに公開する
  • 値を取得および設定する関数をいくつか作成します(ゲッターとセッター)

元のクラスを変更したくない場合(それは混乱したくないサードパーティのライブラリであるため)、元のクラスを拡張するカスタムクラスを作成します。

class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}

...ゲッター/セッターを追加します。

22

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はサポートされている最も古いバージョンです 。最新バージョン。

88
drewish

オブジェクトは(連想)配列に型キャストでき、保護されたメンバーにはchr(0).'*'.chr(0)のプレフィックスが付いたキーがあります(@fardelianのコメント here を参照)。この機能を使用して、「エクスポーザー」を作成できます。

function getProtectedValue($obj,$name) {
  $array = (array)$obj;
  $prefix = chr(0).'*'.chr(0);
  return $array[$prefix.$name];
}

あるいは、 serialized stringの値を解析することもできます。この場合、保護されたメンバーには同じ接頭辞が付けられているようです(php 5.2で変更されていないと思います)。

44
Jan Turoň

ゲッターとセッターを追加せずにクラスをいじりたい場合...

PHP 7では、クロージャーにcall($ obj)メソッド(古いbindToよりも高速)が追加されているため、関数を呼び出して$this変数は、完全な権限を持つクラス内の場合と同じように機能します。

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

元のクラスを変更できず、拡張することもオプションではない場合、ReflectionPropertyインターフェイスを使用できます。

Phptoolcaseライブラリには、このための便利なメソッドがあります。

$value = PtcHandyMan::getProperty( $your_object , ‘propertyName’);

シングルトンクラスの静的プロパティ:

$value = PtcHandyMan::getProperty( ‘myCLassName’ , ‘propertyName’);

このツールは次の場所にあります。 http://phptoolcase.com/guides/ptc-hm-guide.html

3
Charlie