1. 程式人生 > >3:許可權修飾符&許可權修飾符的BUG

3:許可權修飾符&許可權修飾符的BUG

#許可權修飾符

  • 許可權修飾符的定義:簡單來說,他就是用來定義類的成員(屬性、方法)的可作用範圍,也就是作用域,修飾符的不同,決定了,這個變數可以在哪些作用域下被訪問到,乃至對變數進行操作;
  • 用來修飾類成員(類成員一般包含,類的屬性、類的方法)的訪問許可權。

##PHP中的修飾符:

  • public (公共的)
  • protected (受保護的)
  • private (私有的)

此文僅記錄public 與 private 修飾符屬性/方法,protected見【繼承篇】

##屬性的訪問位置

  • public 屬性/方法,在任意位置都可以訪問,無論是在類的內部,還是在類例項上訪問,都是可讀可寫的;
  • private 屬性/方法,只能在類中進行訪問,只在類中進行讀寫;

示例:

class Ren{
	public $name = '小明';
	private $money = 20;

	public function shuchu($a){
		var_dump($a);
		var_dump($this->money);
	}
	
}

$a = new Ren();
$a->shuchu('努力!奮鬥!加油!');
var_dump($a->money);//Fatal error
  • 私有屬性和方法,只能在類中使用,類的函式也是一樣,在類的例項上不能直接呼叫類的私有函式,只能通過別的函式,間接呼叫類內的私有函式;這就極大的方便了封裝;

##一個BUG

  • 先看程式碼:
class Ren{
	public $name = '小明';
	private $money = 20;
	public function getMoney($a){
		echo $a->money;
	}
	public function setMoney($a){
		$a->money -= 4;
	}
}

$a = new Ren();
$b = new Ren();

$b->getMoney($b);
$a->setMoney($b);
$b->getMoney($b);
  • 我例項化了兩個例項,這個BUG就是,類中的私有屬性確實是私有的,但是通過例項化之後的例項,卻可以相互影響對方的私有屬性,這肯定是不合理的,我走大馬路上,我能憑空讓人家的錢消失嗎,我們都是人類這個物件下的例項,我不應該,也不能,更是不合理的去隨意修改別人通過勞動的來的金錢;

  • 這個BUG產生的原因是,PHP在實現私有屬性這個特性上,不是以例項物件為單位來進行許可權的控制,而是以類為單位進行許可權的控制;

  • PHP這樣設計的理由是:因為類只宣告一次,而例項則是不確定宣告次數,以類為單位,簡化了判斷模型,提高語言效能;

  • PHP的核心zend引擎,他的判斷是:呼叫者的類與執行上下文的類是否一致,一致就允許操作。aRen,a例項物件的類是Ren,a->setMoney()這個函式也是在Ren類中,所以可以修改,以類內類外為界限來判斷操作是否可行;

  • java,c#也存在這個問題,語言設計之初都是以類為單位進行屬性和方法的許可權控制;

  • 問題是確實存在的,但是在程式碼的風格上,這種寫法也是不推薦的,不應該這麼些程式碼,但是BUG確實存在…