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

PHP路由开发调用其他文件类方法报非静态调用错误如何解决

错误原因

你使用[类名字符串, 方法名]格式作为call_user_func_array的回调参数时,PHP会默认尝试静态调用该类方法,但你定义的Home::index()为普通实例方法,需要依托类实例才能调用,因此触发类型错误。同时你的代码还存在一处隐藏的路由解析逻辑问题,后面同步给出修复方案。

修复代码

1. 修改APP类的Run方法

核心调整为加载控制器后先实例化对象,再用实例发起方法调用:

public function Run()
{
    $url = $this->SplitURL();
    if(file_exists("../app/controller/".strtolower($url[0]).".php"))
    {
        $this->controller = strtolower($url[0]);
        unset($url[0]);
    }
    require "../app/controller/".$this->controller.".php";

    // 新增实例化控制器逻辑,首字母大写匹配控制器类名
    $controllerClass = ucfirst($this->controller);
    $controllerInstance = new $controllerClass();

    if(isset($url[1]))
    {
        // 改用实例判断方法是否存在,更准确
        if(method_exists($controllerInstance, $url[1]))
        {
            $this->method = $url[1];
            unset($url[1]);
        }
    }
    $this->params = array_values($url);
    // 回调传入实例而非类名字符串
    call_user_func_array([$controllerInstance, $this->method], $this->params);
}

2. 修复SplitURL方法的隐藏问题

原方法无参数时返回["home/index"]会导致路由匹配错误,调整为返回默认控制器名即可:

private function SplitURL()
{
    if(empty($_GET['url']))
    {
        return ["home"];
    }
    else
    {
        return explode("/", filter_var(trim($_GET['url'], '/')),FILTER_SANITIZE_URL);
    }
}
其他注意事项
  • 确保所有控制器类名首字母大写,和实例化时的ucfirst处理逻辑匹配
  • 可额外增加类存在判断、方法访问权限判断,提升代码健壮性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:09:03