private方法仅限定义类内部调用,protected限于类、子类及父类调用,越界即Fatal error;二者均不可被外部、同级子类或运行时函数绕过,访问控制是编译期硬性规则。

private 方法不能从类外部调用,protected 方法不能被非子类或非父类代码访问,这是硬性限制,不是警告——PHP 会直接抛出 Fatal error 中断执行。
调用 private 方法会立即崩溃
只要在类外部(包括其他实例、函数、全局作用域)尝试调用 private 方法,PHP 就会终止脚本并报错:Fatal error: Call to private method ClassName::methodName() from context ''。它不给你“试试看”的机会。
-
private只允许在定义它的那个类的内部使用$this->methodName() - 子类无法继承或覆盖
private方法;method_exists($obj, 'xxx')返回false,哪怕方法真实存在 - 反射(
ReflectionMethod)能绕过,但这是运行时干预,不属于正常调用路径
protected 方法只对继承链开放
protected 比 private 宽松一点,但仍有明确边界:只能被当前类、其子类、以及父类中定义的方法调用。一旦跳出这个链条,就会触发同样的 Fatal error。
- 子类可以调用
parent::methodName()或直接$this->methodName() - 同级子类之间不能互相调用对方的
protected方法(即使继承自同一父类) - 静态上下文中,
self::和static::对protected的行为一致,但static::在后期静态绑定下可能触发更严格的检查
别指望运行时“悄悄降级”
PHP 不会把 private 或 protected 方法自动转成 public,也不会因环境(如开发模式)放宽限制。访问控制是编译期就确定的语义规则。
-
__call()和__callStatic()无法拦截对private/protected方法的直接调用——它们只处理未定义方法 - 即使你用
eval()或call_user_func_array(),只要目标是私有/受保护方法,照样报错 - 自动加载(autoload)成功、类存在、方法拼写正确,都不足以绕过访问修饰符检查
调试时容易忽略的关键点
错误信息里往往不提“权限”,只说“未定义方法”或“不可访问”,尤其当方法名拼错 + 权限不对同时发生时,method_exists() 返回 false,容易误判为方法不存在。
立即学习“PHP免费学习笔记(深入)”;
- 先确认方法是否存在:
var_dump(method_exists($obj, 'xxx')); - 再确认调用上下文是否合法:当前是不是该类或其子类内部?是不是通过对象实例调用?
- 如果必须跨类访问逻辑,应重构为
public接口,或用protected+ 模板方法模式暴露可控入口



















