PHPでクラスのインスタンスのprotected/privateプロパティを取り出してみる

ソースコード

<?php
class MyArgumentError extends Exception{}

// クラスのインスタンスのプロパティを取得
// プロパティのアクセス制御子が非公開(protected/private)であっても取得出来ます。
function get_instance_property($obj, $propName){
    if( !is_object($obj) || !is_string($propName) ){
        throw new MyArgumentError();
    }
    $arr = (array)$obj;
    $keys = array(
         $propName
        ,"\0*\0".$propName
        ,"\0".get_class($obj)."\0".$propName
    );
    foreach( $keys as $key ){
        if( array_key_exists($key, $arr) ){
            return $arr[$key];
        }
    }
    return null;
}

// サンプルクラス
class Hoge{
    static function staticMethod(){}
    public function publicMethod(){}
    protected function protectedMethod(){}
    private function privateMethod(){}
    
    static $staticProperty = 'static';
    public $publicProperty = 'public';
    protected $protectedProperty = 'protected';
    private $privateProperty = 'private';
}

$hg = new Hoge;

$val = get_instance_property($hg, 'staticProperty');
echo (is_null($val)? 'NULL' : $val).'<br>';
$val = get_instance_property($hg, 'publicProperty');
echo (is_null($val)? 'NULL' : $val).'<br>';
$val = get_instance_property($hg, 'protectedProperty');
echo (is_null($val)? 'NULL' : $val).'<br>';
$val = get_instance_property($hg, 'privateProperty');
echo (is_null($val)? 'NULL' : $val).'<br>';

実行結果(実行環境 : PHP 5.2.9-2)。
?>

NULL
public
protected
private

オブジェクトを配列にキャストした場合、

  • publicプロパティは"プロパティ名"
  • protectedプロパティは"\0*\0"."プロパティ名"
  • privateプロパティは"\0"."クラス名"."\0"."プロパティ名"

のキーで取り出せた。
まあ、使う機会はないと思うが。

以下のサイトを参考にしたが、思った通りの結果が得られなかったので躍起になってunpackとか使って調べた。後悔はしていない。

参考サイト。