類型的訪問修飾符允許開發人員對類成員的訪問進行限制,這是PHP5的新特性,但卻是OOP語言的一個好的特性。而且大多數OOP語言都已支持此特性。PHP5支持如下3種訪問修飾符:
public (公有的、默認的),protected (受保護的)和private (私有的)三種。
public 公有修飾符,類中的成員將沒有訪問限制,所有的外部成員都可以訪問(讀和寫)這個類成員(包括成員屬性和成員方法),在PHP5之前的所有版本中,PHP 中類的成員都是public的,而且在PHP5中如果類的成員沒有指定成員訪問修飾符,將被視為public 。例:
public $name; public function say(){ };
private 私有修改符,被定義為private的成員,對於同一個類里的所有成員是可見的,即沒有訪問限制;但對於該類的外部代碼是不允許改變甚至讀操作,對於該類的子類,也不能訪問private修飾的成員。例:
private $var1 = 'A'; // 屬性 private function getValue(){ } // 函數
類內部訪問方式為:$this->var1,$this->getValue()
protected保護成員修飾符,被修飾為protected的成員不能被該類的外部代碼訪問。但是對於該類的子類有訪問權限,可以進行屬性、方法的讀及寫操作,該子類的外部代碼包括其的子類都不具有訪問其屬性和方法的權限。
例:
protected $name; protected function say(){ };
private | protected | public | |
同一個類中 | √ | √ | √ |
類的子類中 | √ | √ | |
所有的外部成員 | √ |
屬性訪問控制示例:
<?php /** * Define MyClass */ class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj = new MyClass(); echo $obj->public; // Works echo $obj->protected; // Fatal Error echo $obj->private; // Fatal Error $obj->printHello(); // Shows Public, Protected and Private /** * Define MyClass2 */ class MyClass2 extends MyClass { // We can redeclare the public and protected method, but not private protected $protected = 'Protected2'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj2 = new MyClass2(); echo $obj->public; // Works echo $obj2->private; // Undefined echo $obj2->protected; // Fatal Error $obj2->printHello(); // Shows Public, Protected2, not Private ?>
方法訪問控制示例:
<?php /** * Define MyClass */ class MyClass { // Contructors must be public public function __construct() { } // Declare a public method public function MyPublic() { } // Declare a protected method protected function MyProtected() { } // Declare a private method private function MyPrivate() { } // This is public function Foo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); } } $myclass = new MyClass; $myclass->MyPublic(); // Works $myclass->MyProtected(); // Fatal Error $myclass->MyPrivate(); // Fatal Error $myclass->Foo(); // Public, Protected and Private work /** * Define MyClass2 */ class MyClass2 extends MyClass { // This is public function Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // Fatal Error } } $myclass2 = new MyClass2; $myclass2->MyPublic(); // Works $myclass2->Foo2(); // Public and Protected work, not Private ?>
另外在子類覆蓋父類的方法時也要注意一點,子類中方法的訪問權限一定不能低於父類被覆蓋方法的訪問權限,也就是一定要高於或等於父類方法的訪問權限。
例如,如果父類方法的訪問權限是protected,那么子類中要覆蓋的權限就要是protected和public,如果父類的方法是public那么子類中要覆蓋的方法只能也是public,總之子類中的方法總是要高於或等於父類被覆蓋方法的訪問權限。