.phpstan/MIGRATION_GUIDE.md
This guide helps developers migrate from direct $GLOBALS access to using OEGlobalsBag.
mixed$GLOBALS superglobal dependency$siteName = $GLOBALS['sitename'];
$timeout = $GLOBALS['timeout'];
$webRoot = $GLOBALS['webroot'];
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
$siteName = $globals->get('sitename');
$timeout = $globals->get('timeout');
$webRoot = $globals->get('webroot');
use OpenEMR\Common\Crypto\CryptoGen;
$cryptoGen = new CryptoGen();
$apiKey = $cryptoGen->decryptStandard($GLOBALS['gateway_api_key']);
$password = $cryptoGen->decryptStandard($GLOBALS['database_password']);
use OpenEMR\Core\OEGlobalsBag;
use OpenEMR\Common\Crypto\CryptoGen;
$globals = OEGlobalsBag::getInstance();
$cryptoGen = new CryptoGen();
// Note: You still need CryptoGen to decrypt encrypted values
$apiKey = $cryptoGen->decryptStandard($globals->get('gateway_api_key'));
$password = $cryptoGen->decryptStandard($globals->get('database_password'));
$GLOBALS['some_setting'] = 'new value';
$GLOBALS['another_setting'] = 42;
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
$globals->set('some_setting', 'new value');
$globals->set('another_setting', 42);
For classes, prefer dependency injection over singleton:
namespace OpenEMR\Services;
use OpenEMR\Core\OEGlobalsBag;
class MyService
{
private OEGlobalsBag $globals;
public function __construct(OEGlobalsBag $globals)
{
$this->globals = $globals;
}
public function doSomething(): void
{
$setting = $this->globals->get('some_setting');
// use $setting
}
}
// Usage
$globals = OEGlobalsBag::getInstance();
$service = new MyService($globals);
namespace OpenEMR\Services;
use OpenEMR\Core\OEGlobalsBag;
class MyService
{
public function doSomething(): void
{
$globals = OEGlobalsBag::getInstance();
$setting = $globals->get('some_setting');
// use $setting
}
}
if (isset($GLOBALS['some_key'])) {
$value = $GLOBALS['some_key'];
}
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
if ($globals->has('some_key')) {
$value = $globals->get('some_key');
}
foreach ($GLOBALS as $key => $value) {
// process each global
}
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
foreach ($globals as $key => $value) {
// process each global
}
// Before
$timezone = $GLOBALS['gbl_time_zone'] ?? 'UTC';
// After
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
$timezone = $globals->get('gbl_time_zone', 'UTC'); // with default
// Before
$dbHost = $GLOBALS['host'];
$dbName = $GLOBALS['dbase'];
// After
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
$dbHost = $globals->get('host');
$dbName = $globals->get('dbase');
// Before
$enableFeature = $GLOBALS['enable_some_feature'];
// After
use OpenEMR\Core\OEGlobalsBag;
$globals = OEGlobalsBag::getInstance();
$enableFeature = $globals->get('enable_some_feature');
OEGlobalsBag makes testing easier:
use PHPUnit\Framework\TestCase;
use OpenEMR\Core\OEGlobalsBag;
class MyServiceTest extends TestCase
{
public function testSomething(): void
{
// Create a test instance with known values
$testGlobals = new OEGlobalsBag([
'some_setting' => 'test value',
'timeout' => 60
]);
$service = new MyService($testGlobals);
// Test your service
}
}
You don't need to migrate everything at once:
OEGlobalsBag$GLOBALS access in that sectionThe new ForbiddenGlobalsAccessRule will catch direct $GLOBALS access in your code:
------ ERROR -------------------------------------------------------
Direct access to $GLOBALS is forbidden. Use OEGlobalsBag::getInstance()->get() instead.
💡 See .phpstan/README.md and .phpstan/MIGRATION_GUIDE.md for migration patterns.
See src/Core/OEGlobalsBag.php for the full implementation and available methods.