iT邦幫忙

1

請問php有沒有函式可以判斷物件屬性的可見性是 private

class xxx{
	public $aaa = 'aaa';
	public $bbb = 'bbb';
	private $ccc = 'ccc';
	
	public function getVars(){
		foreach($this as $x=>$y){
			echo $x . ': ' . $y . '<br />';
		}
	}
}
$xxx = new xxx();
$xxx->getVars();


getVars() 方法會取得所有屬性
但我想只要取得 public 的屬性
請問php有沒有函式可以判斷物件屬性的可見性是 private

2 個回答

6
fillano
iT邦超人 1 級 ‧ 2016-07-19 20:42:51
最佳解答

PHP 支援 Reflection,你可以用它來收集類別資訊,例如:

<?php
class xxx {
    public $a = 'a';
    protected $b = 'b';
    private $c = 'c';
    static $d = 'd';
}
$r = new ReflectionObject(new xxx);
echo $r->getProperty('a') . ' : ' . print_r(Reflection::getModifierNames($r->getProperty('a')->getModifiers()),true);
echo "<br>\n";
echo $r->getProperty('b') . ' : ' . print_r(Reflection::getModifierNames($r->getProperty('b')->getModifiers()),true);
echo "<br>\n";
echo $r->getProperty('c') . ' : ' . print_r(Reflection::getModifierNames($r->getProperty('c')->getModifiers()),true);
echo "<br>\n";
echo $r->getProperty('d') . ' : ' . print_r(Reflection::getModifierNames($r->getProperty('d')->getModifiers()),true);

輸出的結果像這樣:

Property [ public $a ] : Array ( [0] => public ) 
Property [ protected $b ] : Array ( [0] => protected ) 
Property [ private $c ] : Array ( [0] => private ) 
Property [ public static $d ] : Array ( [0] => public [1] => static )

細節請詳閱公開說明書:Reflection

samjam iT邦新手 4 級 ‧ 2016-07-20 09:59:18 檢舉
class xxx{
	public $aaa = 'aaaaa的值';
	public $bbb = 'bbbbb的值';
	protected $ccc = 'ccccc的值';
	protected $ddd = 'ddddd的值';
	private $eee = 'eeeee的值';
	private $fff = 'fffff的值';
	
	public function getVars(){		
		$class = new ReflectionClass('xxx');
		
		// 取得 xxx 類別內 public 的屬性,回傳值為陣列
		// 每個陣列元素是物件,該物件的屬性 name 儲存了 public 的屬性名,但沒有屬性值
		$props = $class->getProperties(ReflectionProperty::IS_PUBLIC);
		
		// 將 public 的屬性名存在陣列中
		$arr = array();
		foreach($props as $i){
			$arr[] = $i->name;
		}
		
		// 遍歷屬性,只顯示 public 的屬性值
		foreach($this as $x=>$y){
			if(in_array($x, $arr)){
				echo $y . '<br />';
			}			
		}
	}
}
$xxx = new xxx();
$xxx->getVars();

/*
謝謝 fillano。
依照您的回答,用上面的方式可以達成了。
但覺得上面程式中 [ 將 public 的屬性名存在陣列中 ] 這個步驟有點多餘,
是否有可以直接取得屬性值的方式呢?
謝謝
*/
fillano iT邦超人 1 級 ‧ 2016-07-20 10:23:17 檢舉

ReflectionProperty有$name屬性及getName()、getValue()方法,所以直接對$props處理就可以了。

class xxx {
    public $a = 'aaa';
    public $b = 'bbb';
    public $c = 'ccc';
}
$o = new xxx;
$r = new ReflectionObject($o);
$p = $r->getProperties(ReflectionProperty::IS_PUBLIC);
foreach($p as $i) {
    echo $i->name . " : " . $i->getValue($o) . "<br>\n";
}

顯示:

a  : aaa
b : bbb
c : ccc
samjam iT邦新手 4 級 ‧ 2016-07-20 13:41:52 檢舉

您這個方式完全解決我的問題了,謝謝fillano

2
weiclin
iT邦高手 4 級 ‧ 2016-07-19 18:25:37
class xxx{
    public $aaa = 'aaa';
    protected $bbb = 'bbb';
    private $ccc = 'ccc';
}
$xxx = new xxx();

foreach (get_object_vars($xxx) as $x => $y) {
    echo $x . ': ' . $y . '<br />';
}
samjam iT邦新手 4 級 ‧ 2016-07-20 09:48:30 檢舉

我希望是放在類別內的方法
用判斷 public / protected / private 的方式來顯示屬性
謝謝 weiclin 的回答

weiclin iT邦高手 4 級 ‧ 2016-07-20 10:32:34 檢舉

那你可以用繼承的方式, 因為父類別不能存取子類別的 private, 所以就會濾出 public 與 protected, 你在子類別避免使用 protected 即可:

class xxxParent {
    public function getVars()
    {
        foreach (get_object_vars($this) as $x => $y) {
            echo $x . ': ' . $y . '<br />';
        }
    }
}

class xxx extends xxxParent{
    public $aaa = 'aaa';
    protected $bbb = 'bbb';
    private $ccc = 'ccc';
}
$xxx = new xxx();
$xxx->getVars();
samjam iT邦新手 4 級 ‧ 2016-07-20 13:40:14 檢舉

謝謝weiclin的回答

我要發表回答

立即登入回答