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
广告