2011年7月29日金曜日

【PHP】private変数をpublic変数っぽくする

久しぶりのプログラミングネタです。
もはやグルメブログと化してます。

やりたいことはタイトルの通りで、CodeIgniterとかのフレームワークに変数をセットする際、メンバ変数にアクセスしたいと思って考えました。
まぁ、private変数をpublic変数として扱おうとしている時点で設計が間違っている気がしないでもないですが。。

さて、
PHPはオブジェクトを配列にキャストできるのですが、
http://d.hatena.ne.jp/shimooka/20071116/1195176801
こことか

この時private変数もキャストされます。ただしkeyが特殊なのでそのままではアクセスできません。
http://www.psi-net.co.jp/blog/?p=302
ここなんかわかりやすいです。



class Test{
    private $test;
    public function setTest($val) {$this->test = $val;}
}

$t = new Test();
$t->setTest("this is test");
$tArr = (array)$t; // arrayにキャスト

print_r($tArr['\000Test\000test']); // private変数にアクセス



こんな感じでアクセスできます。
しかし毎回制御文字を入力するのはめんどくさいので、keyを置換します。
むしろこっちの方がメインかもしれないですね。

keyの置換はarray_keysと、array_valuesと、array_combineを使います。



$arr = array("key1" => "val1", "key2" => "val2", "key3" => "val3");
$keys = array_keys($arr);
$vals = array_values($arr);

foreach($keys as &$key){
    $key = str_replace("key", "KEY", $key); // keyの置換preg_replaceを使ってもよい
}
$newArr = array_combine($keys, $vals); // keyを置換した配列


多次元配列の場合は再帰関数にすればうまくいくかと。


さて、タイトルのprivate変数にpublic変数っぽくアクセスする方法ですが、上の2つを組み合わせます。

class Test{
    private $test;
    public function setTest($val) {$this->test = $val;}
}

$t = new Test();
$t->setTest("this is test");
$tArr = (array)$t; // arrayにキャスト

$keys = array_keys($tArr);
$vals = array_values($tArr);

foreach($keys as &$key){
    $key = preg_replace('/\000(.+)\000/', '', $key); // 制御文字に挟まれた部分を削除
}
$newArr = array_combine($keys, $vals); // keyを置換した配列


これでprivateの変数にもpublicっぽくアクセスできます。


上にも書きましたが、これを使うぐらいなら設計からやり直した方がよい気がしますが。
何かの役に立てば。


ではでは。


0 件のコメント:

コメントを投稿