PHP访问修饰符怎么用?

文章导读
Previous Quiz Next 在 PHP 中,关键字 public、private 和 protected 被称为 访问修饰符。这些关键字控制 class 属性和方法的访问范围或可见性。在声明成员变量和定义成员函数时,需要在前面加上这些关键字之一。
📋 目录
  1. A PHP 中的访问修饰符
  2. B 面向对象编程中的访问控制
  3. C Public 成员
  4. D 私有成员
  5. E 受保护成员
  6. F 访问规则
A A

PHP - 访问修饰符



Previous
Quiz
Next

在 PHP 中,关键字 public、privateprotected 被称为 访问修饰符。这些关键字控制 class 属性和方法的访问范围或可见性。在声明成员变量和定义成员函数时,需要在前面加上这些关键字之一。

PHP 中的访问修饰符

PHP 代码是否可以自由访问 class 成员、是否被限制访问,或者是否具有条件访问,由这些关键字决定 —

  • Public − class 成员可以从任何地方访问,即使是在 class 作用域外部,但必须通过对象引用。

  • Private − class 成员只能在 class 内部访问。它防止 class 外部通过 class 实例引用访问成员。

  • Protected − 成员只能在 class 及其子 class 中访问,其他地方均不可访问。

数据封装原则是面向对象编程方法论的基石。它指的是将对象的数据成员或属性与 class 外部环境隔离的机制,只允许通过 class 中提供的方法或函数进行受控访问。

面向对象编程中的访问控制

为了实现封装,class 的数据成员被设置为 private,而方法被设置为 public

Access Modifiers 1

上图展示了面向对象编程中访问修饰符的使用,主要说明了 public 和 private 成员如何与 class 外部代码交互。

Private 数据成员只能在 class 内部访问。红色“X”表示 class 外部代码无法直接访问私有成员。

Public 函数可以通过对象引用从 class 外部访问。Public 函数通常用于安全地访问 private 数据。

显然,private 属性如何对外部世界隐藏,这实现了封装,这是 OOP 的基本原则之一。

Public 成员

在 PHP 中,class 成员(包括成员变量和成员函数)默认都是 public。

示例

在下面的程序中,对象的成员变量 title 和 price 在 class 外部可以自由访问,因为它们默认是 public,除非另有指定。

<?php
   class Book {
      /* 成员变量 */
      var $price;
      var $title;

      /*构造函数*/
      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 {
      /* 成员变量 */
      private $price;
      private $title;

      /*构造方法*/
      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

受保护成员

为类成员指定 protected 访问权限的效果在类继承的情况下才会显现。我们知道,public 成员可以从类外部的任何地方访问,而 private 成员则被拒绝从类外部的任何地方访问。

protected 关键字允许同一类对象及其继承类的对象访问,拒绝其他环境访问。

让我们在 Book 类示例中将 title 成员设置为 protected,price 保持为 private。

class Book {
   /* 成员变量 */
   private $price;
   protected $title;
   # 其余代码保持不变
}
$b1 = new Book();
$b1->getTitle();
$b1->getPrice();

PHP 允许访问这两个成员变量,因为对象属于同一类。

让我们添加一个 mybook 类,它继承 Book 类 −

class mybook extends Book {
   # 未定义额外成员
}

它的对象仍然能够访问成员变量,因为子类继承了父类的 public 和 protected 成员。

然而,将 mybook 类作为独立类(不继承 Book 类)并定义一个 getmytitle() 函数,该函数试图访问 Book 类的 protected 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