權限修飾符
作用: 用來說明 屬性/方法的權限特點
寫在 屬性/方法前面
共有3個權限修飾符
private 私有的 , 保護的最嚴
protected 保護的
public 公共的 ,保護的最鬆
疑問:
public修飾的屬性/方法,可以在哪兒訪問?private 修飾的屬性/方法,可以在哪兒訪問?
如何判斷屬性/方法 有沒有權限訪問?
答:看訪問時的位置!
private的屬性/方法,只能在類定義的大括號內{},才能訪問
public 的屬性, 在任意位置都可以訪問
class Human {
public $mood = ''; // 心情,公有
private $money = 1000; // 錢,私有
public function showMoney() {
return $this->money;
}
private function secret() {
echo '我小時候偷吃過一塊肉';
}
public function tellMe() {
$this->secret();
}
}
$lisi = new Human();
$lisi->mood = 'happy';
echo $lisi->mood,'<br />'; // happy;
$lisi->money = 500; // 調用位置在Human類的{}外面 ,因此,調用失敗
echo $lisi->money; // 調用位置在Human類的{}外面 ,因此,調用失敗
echo $lisi->showMoney(),'<br />'; //showMoney是公共的,在此行可以調用,return $this->money; 這一句運行的環境是在 類的{}內部,因此有權限訪問 money屬性。
$lisi->secret(); // 不可以
$lisi->tellMe(); // 可以,因爲是通過$this->secret();調用,即類內調用的.
總結: private權限控制,只能在類的{} 內調用,走出了{}, 誰也調不動.
權限控制的bug
class Human {
private $money = 1000;
public function getMoney($people) {
return $people->money;
}
public function setMoney($people) {
$people->money -= 500;
}
}
$zhangsan = new Human();
$lisi = new Human();
// echo $lisi->money; // 不行
// 讓李四去打探張三的錢
echo $lisi->getMoney($zhangsan),'<br />';
// 讓李四去改變張三的錢
$lisi->setMoney($zhangsan);
echo $lisi->getMoney($zhangsan),'<br />';
print_r($zhangsan);
/**
奇怪之處在於,
zhangsan的錢,應該有zhangsan來調用getMoney和setMoney才能影響.
但是和我們前一頁面所寫的原則是符合的:
即:
調用 getMoney,public,有權.
getMoney() 又在類的{}內,有權讀取私有屬性money
調用setMoney,public 有權
setMoney()修改zhangsan的money,發生在類的{}內,有權操作
十八哥的總結
李四讀取和改變張三的錢,這如果從生活角度來看,是不合理的
錢私有,是指 “每個對象的錢,針對每個對象私有”;即:張三的錢,由張三->showMoney才能引用.
李四不應該有權直接引用,或者說,李四->showMoney,也只有權引用李四自己的money屬性.
但是,在上面的代碼中,李四卻顯然引用和改爲張三的錢.
這是因爲:
PHP在實現上,並不是以對象爲單位來控制的權限.而是以類爲單位,來控制的權限,所以前一頁,不斷強調 ,類內,類外,而不是說對象內,對象外.
因爲 類聲明一次,而對象卻可能非常多.以類爲單位,簡化了判斷模型.
第三,從代碼的來看
zend引擎
ce==EG(scope)
這一句判斷的是
調用者屬性的類 與 執行上下文所屬的類 是否相等
在我們判斷中:
在同一個類內部,可以調用.
這也說明了,確實是以類爲單位,以類內類外爲界限做的判斷
case ZEND_ACC_PRIVATE:
if ((ce==EG(scope) || property_info->ce == EG(scope)) && EG(scope))
{
return 1;
} else {
第四
從其他語言來看一看這個問題.java c#,也存在此問題
第五: 從面向對象的角度來考試
我們的寫法,也有問題就不應該把一個對象,直接傳給一個方法來使用
而應該 zhangsan borrow錢,應該對應 lisi sent錢
即 應該儘量的來調用對象的方法,而不應該直接把對象當成參數給傳過去.