Skip to content
Nibiru docsv0.9.2

Registry

How modules are auto-discovered and their configs cached for runtime access.

Stable Reading time ~ 2 min Edit on GitHub

The Registry is Nibiru’s module-config cache. At boot it walks every directory under application/module/, parses each module’s settings/*.ini, and exposes the parsed config through a single accessor. Think of it as the gravitational centre that keeps modules in orbit around each other.

For each module under application/module/<name>/settings/:

  1. The Registry iterates files matching *.ini.
  2. For each, it tries the environment-specific filename first (<base>.<env>.<ext>, e.g. users.production.ini); falls back to the base name (users.ini).
  3. It calls parse_ini_file($path, true) (multi-section).
  4. It looks for a section named after the module, uppercased[USERS], [CMS], [ANALYTICS].
  5. The parsed key/value pairs become an \stdClass keyed by the module name.
$users = \Nibiru\Registry::getInstance()->loadModuleConfigByName('users');
$users->session_lifetime;
$users->password_min_length;
$users->allowed_roles; / array

Inside the module itself the convention is to wrap this in a setter:

class Users extends ModuleAdapter implements IModule
{
const CONFIG_MODULE_NAME = 'users';
protected static \stdClass $usersRegistry;
protected function setUsersRegistry(): void {
self::$usersRegistry = Registry::getInstance()
->loadModuleConfigByName(self::CONFIG_MODULE_NAME);
}
public static function lifetime(): int {
return (int) self::$usersRegistry->session_lifetime;
}
}

INI section names are conventionally uppercased to make them visually distinct. The Registry assumes this, so a module called cms looks for [CMS]. Always uppercase.

Nothing stops you from having more than one INI file in a module’s settings/ folder. The Registry parses them all and merges everything matching [<MODULE>] into the same \stdClass. Useful for splitting concerns:

application/module/users/settings/
├── users.ini # [USERS] base config
├── users.smtp.ini # [USERS] mail-related keys
└── users.production.ini # production override
ConfigRegistry
Sourcesettings.<env>.ini (one file)per-module INIs (many files)
Scopeapp-wide framework configmodule-specific config
Sectionsmixed (DATABASE, SETTINGS, ENGINE…)one per module
LookupConfig::getInstance()->getConfig()['DATABASE']['driver']Registry::getInstance()->loadModuleConfigByName('users')

A module that needs to read [DATABASE] driver reaches for Config. A module that needs to read its own [USERS] session_lifetime reaches for Registry.

$registry = \Nibiru\Registry::getInstance();
foreach ($registry->getModuleNames() as $name) {
$cfg = $registry->loadModuleConfigByName($name);
echo "$name → " . print_r($cfg, true) . "\n";
}

Useful in a debug controller or admin dashboard.

Like Config, the Registry is a singleton populated once per request. If you change a module’s INI you need to refresh the request to see the new values. There’s a destroy() method on the Registry singleton if you really need to reload mid-request, but in normal flows you won’t.

  • Section name doesn’t match the module folder. Folder users/, expected section [USERS]. Mismatch → empty config.
  • INI file extension. Only *.ini is parsed. A *.conf or *.config file is ignored.
  • Environment file beats base file silently. If users.production.ini exists with [USERS] it shadows users.ini entirely — not merged. Keep both files in sync, or use one + an overlay.