global 无法避免耦合,反而是强耦合的根源;PHP 7.1 未改进 global,仅增强类常量可见性以减少其他耦合;替代方案为显式传参、依赖注入容器或构造注入。

global $var 会隐式绑定全局变量,这不是“避免耦合”,而是制造耦合
直接结论:global 本身无法用来“避免耦合”,它天生就是耦合的放大器。PHP 7.1 没给 global 加任何新能力,也没修复它的设计缺陷——它只是让类常量支持 private 和 protected,反而更凸显了 global 的过时。
常见错误现象:function save() { global $pdo; $pdo->exec(...); } 看似省事,实则把数据库连接硬编码进函数逻辑,导致该函数无法脱离当前全局环境运行。
- 函数行为完全依赖外部变量名是否拼对、是否已初始化
- 单元测试时必须手动设置
$pdo,且不能隔离多个测试用例的修改 - 一旦全局
$pdo被 unset 或重赋值,所有用到它的函数集体失效
替代 global 的三种实际可行路径(PHP 7.1+)
真正能降低耦合的不是怎么用 global,而是彻底绕开它。PHP 7.1 及以上版本提供了更现代、更可控的选项:
-
显式传参:最简单直接。把需要的东西当参数传进来,比如
function save($pdo, $data) { ... }。调用方决定传什么,函数不关心来源。 -
依赖注入容器:Laravel 的
app('db')、Symfony 的$container->get('database.connection'),或自建轻量容器,统一管理对象生命周期和依赖关系。 -
类属性 + 构造注入:把状态封装进类,通过构造函数接收依赖:
class UserService { private $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } }
注意:$GLOBALS['pdo'] 不是替代方案,它比 global $pdo 更难追踪、更易拼错,且同样破坏封装。
立即学习“PHP免费学习笔记(深入)”;
为什么 PHP 7.1 的类常量可见性与 global 无关但值得重视
PHP 7.1 引入 private const 和 protected const,不是为了配合 global,而是为了解决另一类耦合问题:类内部常量被外部随意读取和误用。
使用场景:
- 把配置开关、状态码等只供本类使用的值设为
private const,防止外部代码直接引用造成强依赖 - 子类需继承但不应暴露给用户的常量,用
protected const,比如基类定义的默认超时值 -
public const仅用于明确要对外暴露的契约型常量,如Http::STATUS_OK
示例:class ApiClient { private const TIMEOUT = 5000; public function call() { return $this->request(self::TIMEOUT); } } —— 外部无法写 ApiClient::TIMEOUT,也就不会在别处硬编码这个数值。
遗留代码里 global 怎么安全过渡
如果必须维护老项目,不要试图“优化” global,而应逐步剥离:
- 先用
$GLOBALS['config']替换所有global $config,至少让变量名在代码中显式可搜 - 找到第一个使用
global $db的函数,把它改造成接受PDO参数,并在调用处注入 - 禁止在
include文件里定义变量后指望global能跨作用域生效——include是代码拼接,不是作用域合并
最麻烦的一点:global 让你分不清变量到底来自哪一行代码。调试时 var_dump($GLOBALS) 虽然能看到全貌,但无法回答“这个值是谁在什么时候设的”。这才是耦合最难解的地方。



















