在 PHP 中,关键字 public、private 和 protected 称为 访问修饰符。这些关键字控制类属性和方法的可访问性或可见性范围。在声明成员变量和定义成员函数时,其中一个关键字带有前缀。
PHP 代码是可以自由访问类成员,还是被限制访问,或者它是否具有条件访问,由以下关键字决定 -
关键词 | 描述 |
---|---|
Public | 类成员可以从任何位置访问,甚至可以从类的范围之外访问,但只能通过对象引用。 |
Private | 类成员可以在类本身中访问。它阻止成员从类外部访问,即使使用类实例的引用也是如此。 |
protected | 只能在类及其子类中访问成员,而不能在其他任何位置访问。 |
数据封装原则是面向对象编程方法的基石。它是指使对象的数据成员或属性远离类外部环境的机制,仅允许通过类中可用的方法或函数进行受控访问。
为了实现封装,类的数据成员被设为私有,方法被设为公共。
公共成员:public
PHP 类成员(成员变量和成员函数)默认是公共的。
例子
在下面的程序中,对象的成员变量 title 和 price 可以在类外部自由访问,因为如果没有另行指定,它们在默认情况下是 public 的。
<?php
class Book {
/* 成员变量 */
var $price;
var $title;
/* 构造函数 */
function __construct(string $param1="PHP 基本知识", 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";
?>
它将产生以下输出 -
私有成员:Private
如上所述,封装原则要求成员变量不应直接访问。只有方法才应具有对数据成员的访问权限。因此,我们需要将成员变量设为 private 并将方法设为 public。
<?php
class Book {
/* 成员变量 */
private $price;
private $title;
/* 构造函数 */
function __construct(string $param1="PHP 基本知识", 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() 函数是公共的,能够访问私有成员变量 title 和 price。但是,在尝试直接显示标题和价格时,会遇到错误,因为它们不是公开的。
Price: 380
Fatal error: Uncaught Error: Cannot access private property
Book::$title in hello.php:31
受保护成员:protected
在类继承的情况下,指定对类成员的受保护访问的效果是有效的。我们知道,公共成员可以从类以外的任何位置访问,而私有成员被拒绝从类以外的任何位置访问。
protected 关键字授予对同一类的对象及其继承类的对象的访问权限,从而拒绝任何其他环境访问该对象。
让我们将 Book 类示例中的 title 成员设置为 protected,将 price 保留为 private。
class Book {
/* 成员函数 */
private $price;
protected $title;
# 其余代码保持原样
}
$b1 = new Book();
$b1->getTitle();
$b1->getPrice();
PHP 允许访问两个成员变量,因为对象属于同一个类。
让我们添加一个继承 Book 类的 mybook 类 −
class mybook extends Book {
# 未定义其他成员
}
其对象仍然能够访问成员变量,因为子类继承父类的 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 对象的标题时,会引发一条错误消息,显示无法访问受保护的属性 Book::$title。
例子
尝试运行以下代码 -
<?php
class Book {
private $price;
protected $title;
function __construct(string $param1="PHP 基本知识", int $param2=380) {
$this->title = $param1;
$this->price = $param2;
}
public function getPrice(){
echo "价格: $this->price <br/>";
}
public function getTitle(){
echo "标题: $this->title <br/>";
}
}
class mybook {
public function getmytitle($b) {
echo "标题: $b->title <br/>";
}
}
$b1 = new mybook();
$b = new Book();
$b1->getmytitle($b);
?>
它将产生以下输出 -
Book::$title in /home/cg/root/97848/main.php:18
因此,可以看出,protected 成员只能被同一类和继承类的对象访问。对于所有其他环境,无法访问受保护的成员。
辅助功能规则可归纳为下表 -