[PHP] privateの配列プロパティを取り出す

標準クラスのプロパティの、
privateなやつを参照したい時ってあるじゃないですか。

単純に値を返すアクセサメソッドがあればいいんですが、
そうじゃないとき。

例えば、”SplMaxHeap”クラスの
“heap”プロパティの中身を確認したい時。

<?php
$array = range(1, 5);
$que = new SplMaxHeap();
for ($i = 1; $i <= 5; $i++) $que->insert($i);
print($que->heap);

とやっても、

PHP Notice:  Undefined property: SplMaxHeap::$heap in /workspace/Main.php on line 5

と返ってきて、中身を見れません。

そこで、print_r関数を使うと、
privateも含めてプロパティを一覧表示できるとのことで、
やってみると、

SplMaxHeap Object
(
    [flags:SplHeap:private] => 0
    [isCorrupted:SplHeap:private] => 
    [heap:SplHeap:private] => Array
        (
            [0] => 5
            [1] => 4
            [2] => 2
            [3] => 1
            [4] => 3
        )

)

長げぇw

まぁ、一回だけ表示する分にはいいですが、
次の記事で詳細書きますが、
値を1つ追加する度に、heapがどう変化するか見たかったので、
この出力だとうっとおしかったんですよね。

なので、何とかしてコンパクトに配列にまとめたい。
と思って、次のような関数を書きました。

// $que は↑↑の続き

function get_private_array($str, $property) {
// 引数1:print_rで出力された文字列
// 引数2:プロパティ名など、目印となる文字列
    $tmp = explode("\n", $str);
    $heap = [];
    $flag = FALSE;
    
    foreach ($tmp as $row){
        $pos = strpos($row, $property);
        if ($pos !== FALSE) {
            $flag = TRUE; // 目印の文字列があった場合、それ以降次の処理を行う
            continue;
        }
        
        if ($flag === TRUE) {
            if (strpos($row, "(") !== FALSE) continue; // 最初の"("は飛ばす
            elseif (strpos($row, ")") !== FALSE) break; // 最後の")"が出たらbreak
            
            $heap[] = explode(' ', trim($row))[2]; // スペース区切りの3番目が値
        }
    }
    return $heap;
}

$property = "[heap:SplHeap:private]";
$heap = get_private_array(print_r($que, true), $property);
print('[' . implode(', ', $heap) . "]\n");

=== 出力 ====
[5, 4, 2, 1, 3]

コンパクトにまとまりましたw
イマイチ汎用性はないですが・・・

ちなみに、継承クラスでgetメソッド書けばいいんじゃね?
って一瞬思ったんですが、
親クラスのprivateプロパティは、
子クラスからアクセスできませんでした。

カテゴリーphp

コメントを残す

メールアドレスが公開されることはありません。