private仅限本类访问,protected允许子类访问但禁止外部调用,public无限制;可见性检查基于类定义关系,运行时生效。

直接说结论:三者核心区别就一条——private 只能在定义它的那个类里用,protected 多加一层允许子类访问,public 则完全放开,类内、子类、外部实例都能碰。
为什么 private 在子类里访问不到父类同名成员
这不是 bug,是设计使然。private 的作用域严格绑定到「声明它的那个类」,哪怕子类继承了它,也等于没继承这个成员。子类里写 $this->xxx 查的是子类自己的作用域,父类的 private 成员根本不可见。
- 父类定义
private $data,子类中直接读$this->data会报Fatal error: Uncaught Error: Cannot access private property Parent::$data - 子类无法重写(override)父类的
private方法,哪怕签名一样,也是两个独立方法 - 想让子类能用,必须改成
protected;想彻底隔绝,才用private
protected 允许子类访问,但不允许外部调用
这是最常被误用的一层。很多人以为 protected 是“半公开”,结果在控制器里直接 $obj->prop 就报错。
- 外部代码(比如
$user = new User(); echo $user->name;)访问protected属性或方法,一律触发Fatal error: Cannot access protected property ... - 子类内部可直接访问父类
protected成员,无需parent::前缀(除非同名被覆盖) -
protected成员可以被子类重定义(redeclare),但不能降低可见性(比如子类改private会报错)
public 没有访问限制,但别滥用
它确实最方便,但也最容易破坏封装。PHP 默认所有未声明修饰符的属性/方法都是 public,这点容易被忽略。
立即学习“PHP免费学习笔记(深入)”;
- 类内、子类、外部实例(
$obj->method()或$obj->prop)全部畅通无阻 - 如果属性后续需要加校验逻辑(比如年龄不能为负),
public属性就得全量替换为 getter/setter,成本很高 - 现代 PHP(7.4+)推荐配合类型声明使用
private+public方法控制读写,而不是裸露public属性
真正容易被忽略的点是:PHP 的可见性检查发生在运行时,且不依赖命名空间或文件位置,只看类定义关系。哪怕两个类在同一个文件、甚至同一命名空间,只要不是父子关系,protected 和 private 依然不可见。



















