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

Laravel框架下如何禁止指定类调用全局辅助函数app()

需求可实现,以下是两种常用落地方案

方案1:运行时拦截(符合你给出的代码示例效果)

Laravel的全局辅助函数定义时都会做function_exists判断,你可以在Laravel加载自带辅助函数之前提前定义app()函数,结合调用栈校验实现拦截:

实现步骤

  1. 新建自定义辅助函数文件 app/helpers/custom_app.php,写入以下代码:
<?php
// 全局存储禁止使用指定函数的类列表
$GLOBALS['__forbidden_func_map'] = [];

if (!function_exists('app')) {
    function app($make = null, array $parameters = [])
    {
        // 获取调用app()的类信息
        $callTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
        $callerClass = $callTrace[1]['class'] ?? null;

        // 校验当前类是否被禁止调用app()
        if (
            $callerClass
            && isset($GLOBALS['__forbidden_func_map'][$callerClass])
            && in_array('app', $GLOBALS['__forbidden_func_map'][$callerClass])
        ) {
            throw new \RuntimeException(sprintf('类 %s 禁止直接调用app(),请使用项目封装的权限校验实例创建方法', $callerClass));
        }

        // 走Laravel原生的容器实例获取逻辑
        return \Illuminate\Container\Container::getInstance()->make($make, $parameters);
    }
}

if (!function_exists('forbid_use_of_function')) {
    function forbid_use_of_function(string $funcName)
    {
        $callTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
        $callerClass = $callTrace[1]['class'] ?? null;
        if (!$callerClass) return;

        if (!isset($GLOBALS['__forbidden_func_map'][$callerClass])) {
            $GLOBALS['__forbidden_func_map'][$callerClass] = [];
        }
        if (!in_array($funcName, $GLOBALS['__forbidden_func_map'][$callerClass])) {
            $GLOBALS['__forbidden_func_map'][$callerClass][] = $funcName;
        }
    }
}
  1. 修改composer.json的自动加载配置,让自定义辅助函数优先于Laravel自带的辅助函数加载:
{
    "autoload": {
        "files": [
            "app/helpers/custom_app.php",
            "vendor/laravel/framework/src/Illuminate/Foundation/helpers.php"
        ]
    }
}
  1. 执行composer dump-autoload使配置生效。
    配置完成后你给出的示例代码就会按预期抛出异常。

如果你需要的是「仅允许特定类使用app()」的白名单逻辑,不需要forbid_use_of_function方法,直接在自定义的app()函数里配置允许调用的类列表,不在列表内的调用直接抛异常即可,逻辑更简单。

方案2:静态代码检测(更适合多人协作场景)

如果不想改运行时代码,可以用PHPStan/Psalm等静态检测工具添加自定义规则,代码提交/合并前自动扫描所有调用app()的位置,不符合规则的直接阻断提交,从开发流程层面避免开发者绕过权限逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:06:04