PHP – 訪問修飾符



在PHP中,關鍵字public、privateprotected被稱為訪問修飾符。這些關鍵字控制類屬性和方法的可訪問性或可見性程度。在宣告成員變數和定義成員函式時,會在前面加上其中一個關鍵字。

PHP程式碼是否可以自由訪問類成員,或者是否受限於訪問,或者是否有條件訪問,是由這些關鍵字決定的:

  • Public - 類成員可以從任何地方訪問,即使是在類的作用域之外,但只能透過物件引用訪問。

  • Private - 類成員只能在類本身內部訪問。它阻止外部類訪問成員,即使是透過類例項的引用。

  • Protected - 成員只能在類及其子類內部訪問,其他地方都不能訪問。

資料封裝的原則是面向物件程式設計方法的基石。它指的是將物件的成員變數或屬性與外部環境隔離開來的機制,只允許透過類中提供的成員方法或函式進行受控訪問。

為了實現封裝,類的成員變數被設定為private,而方法被設定為public

Access Modifiers 1

公共成員

在PHP中,類成員(成員變數和成員函式)預設為public,除非另行指定。

示例

在下面的程式中,物件的成員變數title和price可以在類外自由訪問,因為它們預設為public,除非另行指定。

<?php
   class Book {
      /* Member variables */
      var $price;
      var $title;

      /*Constructor*/
      function __construct(string $param1="PHP Basics", int $param2=380) {
         $this->title = $param1;
         $this->price = $param2;
      }

      function getPrice() {
         echo "Title: $this->price \n";
      }

      function getTitle() {
         echo "Price: $this->title \n";
      }
   }
   $b1 = new Book();
   echo "Title : $b1->title Price: $b1->price";
?>

它將產生以下輸出

Title : PHP Basics Price: 380

私有成員

如上所述,封裝原則要求成員變數不能直接訪問。只有方法才能訪問資料成員。因此,我們需要將成員變數設為private,將方法設為public。

<?php
   class Book {
      /* Member variables */
      private $price;
      private $title;

      /*Constructor*/
      function __construct(string $param1="PHP Basics", int $param2=380) {
         $this->title = $param1;
         $this->price = $param2;
      }

      public function getPrice() {
         echo "Price: $this->price \n";
      }

      public function getTitle() {
         echo "Title: $this->title \n;";
      }
   }
   $b1 = new Book();
   $b1->getTitle();
   $b1->getPrice(); 
   echo "Title : $b1->title Price: $b1->price";
?>

輸出

現在,getTitle()和getPrice()函式是public的,可以訪問私有成員變數title和price。但是,當試圖直接顯示title和price時,會遇到錯誤,因為它們不是public的。

Title: PHP Basics
Price: 380
Fatal error: Uncaught Error: Cannot access private property 
Book::$title in hello.php:31

受保護成員

指定受保護訪問對類成員的影響在類繼承的情況下是有效的。我們知道public成員可以從類外部的任何地方訪問,而private成員則被拒絕從類外部的任何地方訪問。

protected關鍵字允許訪問相同類的物件及其繼承類的物件,而拒絕其他任何環境訪問。

讓我們將Book類示例中的title成員設定為protected,將price保留為private。

class Book {
   /* Member variables */
   private $price;
   protected $title;
   # rest of the code kept as it is
}
$b1 = new Book();
$b1->getTitle();
$b1->getPrice();

PHP允許訪問這兩個成員變數,因為物件屬於同一個類。

讓我們新增一個mybook類,它繼承Book類:

class mybook extends Book {
   # no additional members defined
}

其物件仍然可以訪問成員變數,因為子類繼承了父類的public和protected成員。

但是,將mybook類作為一個獨立的類(不擴充套件Book類),並定義一個getmytitle()函式,嘗試訪問Book類的受保護成員變數title。

class mybook {
   public function getmytitle($b) {
      echo "Title: $b->title <br/>";
   }
}
$b1 = new mybook();
$b = new Book();
$b1->getmytitle($b);

由於getmytitle()函式試圖列印Book物件的title,因此會引發一條顯示Cannot access protected property Book::$title的錯誤訊息。

示例

嘗試執行以下程式碼:

<?php
   class Book {
      private $price;
      protected $title;
      function __construct(string $param1="PHP Basics", int $param2=380) {
         $this->title = $param1;
         $this->price = $param2;
      }
      public function getPrice(){
         echo "Price: $this->price <br/>";
      }
      public function getTitle(){
         echo "Title: $this->title <br/>";
      }
   }
   class mybook {
      public function getmytitle($b) {
         echo "Title: $b->title <br/>";
      }
   }
   $b1 = new mybook();
   $b = new Book();
   $b1->getmytitle($b);
?>

它將產生以下輸出

PHP Fatal error:  Uncaught Error: Cannot access protected property 
   Book::$title in /home/cg/root/97848/main.php:18

因此,可以看出受保護成員只能被相同類和繼承類的物件訪問。對於所有其他環境,受保護成員都是不可訪問的。

可訪問性規則可以由下表總結:

Access Modifiers 2
廣告