PHP中通过类实例对象调用静态方法为何不报错?
为什么PHP类的实例对象可以调用静态方法?
我们先看问题对应的可复现代码:
<?php class Student { public static $university; public static function info() { echo "Static Method is called "; } } $s1 = new Student(); $s1->university = "BBBB"; // 触发错误,符合静态属性访问预期 $s1->info(); // 正常执行,没有报错
这个差异是PHP语法层面针对静态属性、静态方法设计的不同访问规则导致的,不是语法bug:
- 静态属性的所有权完全归属于类,和所有实例化对象都没有绑定关系,所以PHP在语法校验阶段就直接禁止了通过对象运算符
->从实例访问静态属性的操作,不管是读取还是赋值,只要写了$实例->静态属性的形式,就会直接抛出错误,这就是给$s1->university赋值时报错的原因。 - 静态方法的访问限制要宽松很多:静态方法本身不依赖
$this上下文,执行时不需要绑定具体实例的状态,所以PHP底层没有禁止通过实例的对象运算符调用静态方法——不管你是用类名::info()的标准静态调用形式,还是用$s1->info()的实例调用形式,PHP只要能定位到这个属于类的方法,就会正常执行,不会抛出错误。
开发提示:虽然语法允许实例调用静态方法,但非常不推荐这种写法。静态方法的语义就是和实例状态无关、归属于类的逻辑,用实例调用会混淆代码语义,所有静态方法统一使用
类名::方法名()的形式调用才是符合规范的写法。
另外要注意:就算你用实例去调用静态方法,方法内部也无法获取到$this指针,如果在静态方法里直接写$this相关逻辑,不管用什么方式调用都会报“不在对象上下文”的错误,这也能印证静态方法本身是脱离实例存在的。
内容的提问来源于stack exchange,提问作者H M Mohidul Islam
相关产品推荐
相关产品推荐

