目录
Understand What $GLOBALS Is Doing in Your Code
Replace Global Variables with Dependency Injection
Step 1: Extract Variables into Configuration or Services
Step 2: Use Constructors or Method Arguments
Use a Configuration Container
Refactor in Small, Safe Steps
Watch Out for Hidden Dependencies
Use Static Analysis and Testing
Summary: Replace $GLOBALS with Explicit Patterns
首页 后端开发 php教程 重构遗产PHP:消除$ GLOBALS的实用指南

重构遗产PHP:消除$ GLOBALS的实用指南

Aug 03, 2025 am 11:14 AM
PHP $GLOBALS

要消除PHP中的$GLOBALS,应首先分析其使用情况,然后通过依赖注入、配置对象和逐步重构替代全局变量。1. 使用grep等工具找出所有$GLOBALS用法,记录键名及位置;2. 将数据库连接、配置等全局变量替换为显式依赖,如通过构造函数注入PDO或Config对象;3. 创建服务类(如Logger、UserService)封装功能,避免函数依赖全局状态;4. 将配置集中管理,从返回数组的配置文件加载,并注入所需类;5. 按步骤小范围重构,每次替换一个$GLOBALS引用,测试确保行为一致;6. 警惕包含文件的副作用,改用显式引入和传递配置;7. 利用PHPStan等工具辅助检测,编写测试防止回归。最终实现代码解耦、可测试、易维护,提升应用的可预测性和协作效率。

Refactoring Legacy PHP: A Practical Guide to Eliminating $GLOBALS

Using $GLOBALS in PHP is a common pattern in legacy applications — especially those built before modern practices like dependency injection and proper object-oriented design became widespread. While $GLOBALS might seem convenient for sharing data across functions and files, it introduces tight coupling, makes testing difficult, and obscures data flow. If you're refactoring legacy PHP code, eliminating $GLOBALS should be a top priority.

Refactoring Legacy PHP: A Practical Guide to Eliminating $GLOBALS

Here’s a practical guide to help you move away from $GLOBALS and build cleaner, more maintainable code.


Understand What $GLOBALS Is Doing in Your Code

Before removing anything, you need to understand how $GLOBALS is being used. In PHP, $GLOBALS is a superglobal array that provides access to all variables in the global scope. For example:

Refactoring Legacy PHP: A Practical Guide to Eliminating $GLOBALS
$apiKey = 'abc123';

function sendRequest() {
    $key = $GLOBALS['apiKey'];
    // use $key
}

Common uses in legacy code:

  • Storing configuration values
  • Sharing state between functions
  • Passing data between included files
  • Acting as a makeshift service container

Start by identifying all instances of $GLOBALS:

Refactoring Legacy PHP: A Practical Guide to Eliminating $GLOBALS
grep -r "\$GLOBALS" ./src/

Document what keys are being used and where (e.g., $GLOBALS['db'], $GLOBALS['user'], $GLOBALS['config']).


Replace Global Variables with Dependency Injection

The core principle: instead of reaching into the global scope, pass dependencies explicitly.

Step 1: Extract Variables into Configuration or Services

Take a global like $GLOBALS['db'] — this likely represents a database connection. Replace it with a dedicated service:

// Before
$GLOBALS['db'] = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

function getUser($id) {
    return $GLOBALS['db']->query("SELECT * FROM users WHERE id = $id");
}

// After
class UserService {
    private $pdo;

    public function __construct(PDO $pdo) {
        $this->pdo = $pdo;
    }

    public function getUser($id) {
        $stmt = $this->pdo->prepare("SELECT * FROM users WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch();
    }
}

Now the dependency is explicit and can be mocked in tests.

Step 2: Use Constructors or Method Arguments

Gradually refactor functions that rely on $GLOBALS to accept parameters:

// Before
function logMessage($msg) {
    $file = $GLOBALS['logFile'];
    file_put_contents($file, $msg . "\n", FILE_APPEND);
}

// After
function logMessage($msg, $logFile) {
    file_put_contents($logFile, $msg . "\n", FILE_APPEND);
}

Eventually, wrap such functionality in a class:

class Logger {
    private $file;

    public function __construct(string $file) {
        $this->file = $file;
    }

    public function log($msg) {
        file_put_contents($this->file, $msg . "\n", FILE_APPEND);
    }
}

Use a Configuration Container

For values like API keys, paths, or settings, replace scattered $GLOBALS['config'] usage with a centralized config array or object:

$config = [
    'api_key' => 'abc123',
    'log_file' => '/var/log/app.log',
    'db_dsn' => 'mysql:host=localhost;dbname=test',
];

Pass this config where needed, or wrap it in a simple class:

class Config {
    private $data;

    public function __construct(array $data) {
        $this->data = $data;
    }

    public function get($key) {
        return $this->data[$key] ?? null;
    }
}

Now inject Config into classes that need settings.


Refactor in Small, Safe Steps

You don’t need to rewrite everything at once. Follow this incremental strategy:

  • Step 1: Identify one $GLOBALS usage (e.g., $GLOBALS['user'])
  • Step 2: Find all read/write locations
  • Step 3: Introduce a setter/getter or service class
  • Step 4: Redirect reads/writes to the new system
  • Step 5: Remove the $GLOBALS reference
  • Step 6: Test thoroughly

Use version control to isolate each change. Write tests if possible — even basic assertions can prevent regressions.


Watch Out for Hidden Dependencies

Some legacy code might rely on side effects from included files that populate $GLOBALS. For example:

// config.php
$GLOBALS['theme'] = 'dark';
$GLOBALS['lang'] = 'en';
// somewhere else
echo "Language: " . $GLOBALS['lang'];

In such cases:

  • Convert the config file to return an array
  • Require it once and pass the result around
  • Or use a config loader class
// config.php
return [
    'theme' => 'dark',
    'lang' => 'en',
];

// bootstrap.php
$config = require 'config.php';
$renderer = new Renderer($config);

Avoid relying on side effects from include/require.


Use Static Analysis and Testing

Tools like PHPStan, Psalm, or even grep can help track down $GLOBALS usage. Write regression tests to ensure behavior stays consistent during refactoring.

If the app lacks tests, start with integration tests around key workflows (e.g., user login, form submission) to catch breakage early.


Summary: Replace $GLOBALS with Explicit Patterns

  • ❌ Avoid: $GLOBALS['db'], $GLOBALS['config'], etc.
  • ✅ Use: Dependency injection, constructor injection, service classes
  • ✅ Centralize config in a Config object or array
  • ✅ Refactor incrementally, not all at once
  • ✅ Test each change

Eliminating $GLOBALS isn’t just about cleaning up syntax — it’s about making your application more predictable, testable, and easier to evolve. The effort pays off quickly in reduced bugs and better team collaboration.

Basically, treat $GLOBALS like technical debt: identify it, isolate it, and replace it with something maintainable.

以上是重构遗产PHP:消除$ GLOBALS的实用指南的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

PHP教程
1543
276
依赖注入:$ GLOBALS的优越替代品 依赖注入:$ GLOBALS的优越替代品 Aug 03, 2025 pm 03:56 PM

Dependencyinjection(DI)issuperiortousing$GLOBALSbecauseitmakesdependenciesexplicit,whereas$GLOBALShidesthem.2.DIimprovestestabilitybyallowingeasymockingofdependencies,unlike$GLOBALSwhichrequiresmanipulatingglobalstate.3.DIreducestightcouplingbydecoup

通过$ GLOBALS的全球国家国家的安全风险 通过$ GLOBALS的全球国家国家的安全风险 Aug 03, 2025 pm 04:20 PM

$ globalsallowsunistendedVariableWriting,EnablingAttAckerStomaniPulateCricalDatalikeUserIdSorrolesRolesSorroleswithOutValidation; 2.ItinCreaseSestHeatTackSurfaceBybreakingSapsulation,makefunctionsDepentFunctionsDepentNepentEndectendentondepentNepentEndepentNepentEndepentNepentEndepentNepentEndectentendepentNepentEndeptentOblobalBalbaltStateThateThatCanblobeD.

单位测试代码的噩梦带有$ Globals 单位测试代码的噩梦带有$ Globals Aug 05, 2025 am 09:06 AM

使用$GLOBALS会破坏单元测试,因为它引入了隐藏依赖,导致测试间状态共享、设置混乱、隔离性差且难以模拟;2.解决方法包括:先保存再恢复全局状态以避免污染;3.将$GLOBALS访问封装到服务类中,通过依赖注入传递,便于在测试中使用模拟对象;4.即使是轻量级的依赖注入也能显着提升可测试性,应避免直接读取全局变量;5.为防止未来问题,应禁用$GLOBALS,改用配置对象、依赖注入容器或环境变量,并借助静态分析工具检测超全局变量使用。最终答案是:必须通过封装和依赖注入逐步消除对$GLOBALS的依

$ GLOBALS与'全局”关键字:了解核心差异 $ GLOBALS与'全局”关键字:了解核心差异 Aug 04, 2025 pm 03:59 PM

$GLOBALS和global都用于在函数中访问全局变量,但存在关键差异:1.$GLOBALS是超全局数组,通过键名访问变量,如$GLOBALS['var'],而global是语言结构,需声明global$var;2.$GLOBALS无需预先声明可直接使用,global必须先声明再使用;3.$GLOBALS支持动态访问,如$GLOBALS[$varName],global不支持动态声明;4.unset($GLOBALS['var'])会删除全局变量本身,而unset($var)在global$v

为什么现代PHP框架使$ Globals过时 为什么现代PHP框架使$ Globals过时 Aug 05, 2025 am 07:39 AM

Modernphpframeworkslikelaravelandsymfonyspoysententiententientsientientientientientientienctionson $ GlobalSbyIndingDippedIsexiesExpliciesExpliciesexplicy.2.2.applicationStateIsnowManagyManagedManagedManagedManagedManagedManagedStrongructionStroffertsSuchasconFigurationserviceserviceserviceserviceserviceservices,r

全球状态的危险:为什么您应该避免PHP的$ Globals 全球状态的危险:为什么您应该避免PHP的$ Globals Aug 03, 2025 am 04:14 AM

Using$GLOBALScreateshiddendependencies,makingfunctionshardertotest,fragile,andunreusable;2.Itcomplicatesunittestingbyrequiringglobalstatemanipulation,leadingtoslow,fragiletests;3.Globalstateisunpredictableduetouncontrolledmodifications,causingbugsand

由$ Globals操纵引起的全球状态混乱 由$ Globals操纵引起的全球状态混乱 Aug 03, 2025 pm 01:46 PM

$GLOBALSmanipulationcancauseunpredictablebugsinPHP;todebugandresolveit,1.Understandthat$GLOBALSprovidesglobalaccesstoallvariables,makingstatechangeshardtotrack;2.DetectunwantedmodificationsusingstrategicdebugloggingandaGlobalsWatcherclasstosnapshotan

驾驶雷区:合法(和罕见的)用例 驾驶雷区:合法(和罕见的)用例 Aug 04, 2025 pm 02:10 PM

Using$GLOBALSmaybeacceptableinlegacysystemslikeWordPresspluginswhereitensurescompatibility,2.Itcanbeusedtemporarilyduringbootstrappingbeforedependencyinjectionisavailable,3.Itissuitableforread-onlydebuggingtoolsindevelopmentenvironments.Despitethesec

See all articles