在 WordPress 中如何优雅的使用全局变量
程序写多了,都会认同这条规则:在 WordPress 中,都尽量不要使用全局变量,其实任何 PHP 程序中都是这样的。为什么?先从简单介绍下全局变量开始。
什么是全局变量
全局变量是在 PHP 脚本的任何作用域中都可以访问的变量,主要包括以下几种形式:
超全局变量 (Superglobals)
PHP 预定义的全局数组,无需使用 global
声明即可在任何作用域访问:
$_GET
:HTTP GET 请求参数$_POST
:HTTP POST 请求参数$_REQUEST
:GET/POST/COOKIE 的合并数据$_SESSION
:会话数据$_COOKIE
:客户端 Cookie 数据$_SERVER
:服务器和执行环境信息$_FILES
:上传文件信息$_ENV
:环境变量$GLOBALS
:所有全局变量的引用集合
使用 global
关键字
在函数或方法内部通过 global
关键字访问全局变量:
$globalVar = 10;
function test() {
global $globalVar;
echo $globalVar; // 输出 10
}
$GLOBALS
数组
直接通过 $GLOBALS
访问全局变量:
$globalVar = 10;
function test() {
echo $GLOBALS['globalVar']; // 输出 10
}
使用全局变量的问题
代码可维护性差
- 隐式依赖:函数内部依赖全局变量会导致代码逻辑不透明,难以追踪数据来源。
- 耦合度高:修改全局变量可能影响多个地方,引发难以调试的副作用。
作用域污染
- 命名冲突:全局变量可能与其他变量或库中的变量同名,导致意外覆盖。
- 生命周期不可控:全局变量在脚本结束前一直存在,可能占用不必要的内存。
并发和线程安全问题
- 在并发环境(如多线程或异步任务)中,全局变量可能被多个线程同时修改,导致数据不一致。
测试困难
- 全局状态使得单元测试难以隔离,测试用例之间可能互相影响。
安全隐患
- 超全局变量(如
$_GET
、$_POST
)未过滤时可能引发安全漏洞(如 SQL 注入、XSS)。
全局变量虽然方便,但过度使用会导致代码质量下降。应该遵循“最小作用域原则”和“单一职责原则”,能显著提升代码的可维护性和安全性。
在 WordPress 中正确使用全局变量
但是我们在代码中还是要使用一些全局变量,或者类似全局变量的变量,比如我在小程序中记录当前登录的用户的 openid:$weapp_openid
。那么怎么办呢?
先上代码:
function wpjam_var($name, ...$args){
static $vars;
$vars ??= wpjam_parse_user_agent(); // 当前用户访问的环境信息
if($args && (!isset($vars[$name]) || !is_closure($args[0]))){
$value = maybe_closure($args[0], $name);
if(is_wp_error($value) || is_null($value)){
return $value;
}
$vars[$name] = $value;
}
return $vars[$name] ?? null;
}
我创建一个 wpjam_var
函数,这个函数创建一个静态变量 $vars
,它是一个数组,所有全局要使用的变量都存到该数组中。
$weixin_openid = '通过小程序插件获取';
// 存储变量
wpjam_var('weapp_openid', $weixin_openid);
然后在之后 $weapp_openid
可以通过以下方法获取:
// 获取变量
wpjam_var('weapp_openid');
它还支持闭包函数,比如我们可以将获取 $weapp_openid
包装成一个函数:
function weapp_get_current_openid(){
return wpjam_var('weapp_openid', function(){
$access_token = wpjam_get_parameter('access_token');
if(!$access_token){
return new WP_Error('illegal_access_token', 'Access Token 为空!');
}
return WEAPP::get_openid_by_access_token($access_token);
});
}
这样在之后的地方都可以使用 weapp_get_current_openid
获取 $weapp_openid
。它的具体如何获取和实现,
最后再总结一下 wpjam_var
函数,它的第一个参数 $name
很简单,变量的名称,第二个参数分三种情况:
- 如果没有设置,就返回该变量的值,没有设置则为
null
。 - 如果是简单的值(非闭包),则设置并返回该值。
- 如果是闭包函数,如设置
$name
的变量,则返回它的值,如果未设置,通过调用闭包函数获得值,然后设置并返回。

wpjam_var
函数的好处
1. 作用域隔离,避免污染
- 数据封闭性
示例中的$weapp_openid
通过wpjam_var
存储,仅限函数内部访问,外部无法直接修改,彻底规避全局变量的命名冲突和意外覆盖。 - 安全访问
所有操作必须通过wpjam_var
函数(如weapp_get_current_openid()
),天然实现私有性,避免全局污染。敏感数据(如access_token
)的获取逻辑封装在闭包内,防止外部直接暴露。
2. 性能优化(延迟初始化)
- 按需加载
示例中$weapp_openid
的闭包函数可能涉及数据库查询,首次调用时执行一次并缓存结果,后续直接复用,避免重复计算。 - 内存级访问速度
静态变量存储在内存中,访问速度远超全局变量或文件读取。同一请求中多次调用weapp_get_current_openid()
时,性能提升显著(如减少冗余 API 调用)。
3. 灵活的数据管理
- 动态惰性计算
通过闭包(如示例中的匿名函数)实现“按需生成数据”,仅在未缓存时触发逻辑,资源利用率更高。 - 错误隔离与健壮性
检测WP_Error
或null
(如access_token
为空时返回错误),避免污染缓存,确保后续逻辑仅处理有效数据。
4. 可维护性与扩展性
- 逻辑集中管理
weapp_get_current_openid()
作为唯一入口,集中维护openid
的获取规则,修改生成逻辑(如更换认证方式)只需调整闭包,无需全局搜索。 - 易于扩展功能
支持快速添加类型检查、日志记录或缓存失效机制(如reset
参数),无需改动外部调用代码,扩展成本低。 - 代码清晰度
数据定义($weapp_openid
)与业务逻辑(闭包)分离,提升可读性,降低维护难度。
5. 安全性提升
- 输入验证与过滤
示例中闭包内对access_token
做非空校验,拦截非法输入(如空值或无效格式),防止无效请求进入下游逻辑。 - 风险隔离
敏感操作(如get_openid_by_access_token()
)封装在闭包中,统一实施安全策略(如加密、超时控制),避免全局变量直接暴露的风险。
6. 适用场景
- 高频请求数据
如示例中的openid
,适用于同一请求内多次访问的场景(如用户信息、权限校验)。 - 动态配置管理
根据环境加载不同配置(如开发/生产环境参数),通过闭包实现按需加载。 - 共享资源访问
替代单例模式,简化数据库连接池等共享资源的管理。
上面这段话,是 deepseek 帮我总结的,果然比我吹的好,但是也说明这个函数实现的好,哈哈!在最新版的 WPJAM Basic 即可直接使用。