
静态方法必须用类名或 self/static 调用,不能用 $this
PHP 静态方法属于类本身,不依赖实例,所以一旦你在非静态上下文中写 $this->methodName(),就会直接报错:Fatal error: Uncaught Error: Using $this when not in object context。这是最常踩的坑——尤其从普通方法里顺手抄代码过来时。
正确调用方式只有三种:
- 类名直接调用:
MyClass::doSomething()(最清晰,推荐用于跨类调用) - 在本类中用
self::doSomething()(绑定定义时的类,不会被继承覆盖) - 在本类中用
static::doSomething()(支持后期静态绑定,子类重写后会调用子类版本)
:: 是静态调用操作符,不是作用域解析符的“别名”
很多人误以为 :: 只是“高级版的 .”,其实它有明确语义:左侧必须是类名、self、static 或 parent,不能是变量或表达式。下面这些写法全错:
-
$className = 'MyClass'; $className::method();→ 报错:Parse error: syntax error, unexpected '::'(PHP 8.2+ 才支持变量类名静态调用) -
$obj::method();→ 即使$obj是MyClass实例,也不行;静态调用不看对象,只看左侧是否为合法类引用 -
new MyClass()::method();→ 语法错误,new表达式不能直接跟::
静态方法里不能访问 $this->property,但可以读 self::$property
静态方法运行时没有对象上下文,所有实例属性都不可见。如果试图读 $this->name,会立刻触发致命错误;但类属性(即静态属性)可以用 self::$count 或 static::$count 访问。
立即学习“PHP免费学习笔记(深入)”;
注意两者的区别:
-
self::$cache指向定义该方法的类的静态属性,哪怕在子类里调用也不会变 -
static::$cache指向实际调用时的类,适合需要子类隔离缓存的场景 - 如果属性没声明为
static,比如public $data;,静态方法里连self::$data都不能用——会警告Accessing static property as non-static
从 PHP 8.2 开始,变量类名静态调用才真正可用
老项目升级时容易在这里翻车:PHP 8.1 及之前,$class = 'MyClass'; $class::method(); 是语法错误;PHP 8.2+ 才允许。如果你的部署环境还没升级,就得绕开:
- 用
call_user_func([$class, 'method'])(兼容性最好) - 用反射:
(new \ReflectionClass($class))->getMethod('method')->invoke(null) - 或者干脆避免动态类名,把分支逻辑收进工厂方法里
这个限制不是设计疏漏,而是因为早期 PHP 解析器无法在编译期确认变量是否真能代表一个类——直到 8.2 引入了更严格的运行时检查。









