You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何PHP类成员方法中调用静态不存在方法时触发__call而非__callStatic?

PHP中__call意外触发而非__callStatic的原因分析

在非静态成员方法内部,使用类名::不存在的静态方法()调用时,PHP会优先将其解析为对象方法调用,而非静态方法调用,这就是为什么__call被触发而不是预期的__callStatic。

核心原因

当代码处于非静态上下文(即成员方法内部,此时存在$this对象)时,PHP的方法解析规则会优先绑定到当前对象。即使你写了Test::nonExistingStaticMethod(),PHP仍会尝试在当前对象上查找该方法——找不到时就触发对象的__call魔术方法,而非静态类的__callStatic。

验证与解决

验证:切换到静态上下文

将wtf方法改为静态方法,此时上下文无$this,调用会触发__callStatic:

class Test {
    public function __call($name, $params){
        echo "__call()";
    }
    
    public static function __callStatic($name, $params){
        echo "__callStatic()";
    }
    
    public static function wtf(){
        Test::nonExistingStaticMethod();
    }
}

$test = new Test();
$test->wtf(); // 输出:__callStatic()

解决:强制静态调用(非静态上下文内)

如果需要在非静态方法里触发__callStatic,可以使用forward_static_call强制走静态方法解析流程:

public function wtf(){
    forward_static_call(['Test', 'nonExistingStaticMethod']); // 输出:__callStatic()
}

原问题代码

<?php

class Test {

    public function __call($name, $params){
        echo "__call()";
    }
    
    public static function __callStatic($name, $params){
        echo "__callStatic()";
    }
    
    public function wtf(){
        Test::nonExistingStaticMethod();
    }

}

$test = new Test();
$test->wtf(); // expected: __callStatic , actually: __call

内容的提问来源于stack exchange,提问作者br4nnigan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:05:21