Docs

MLC

MLC is the MonkeysLegion configuration layer: a tiny parser/loader for the human-friendly .mlc file format.

It gives you strongly-typed, immutable config objects without the weight of YAML or the rigidity of PHP arrays.

1 · Installation

composer require monkeyscloud/monkeyslegion-mlc

The package is pure PHP 8.4 – nothing else is pulled in.

 

2 · .mlc syntax at a glance

# comments start with #
app.name       = "MonkeysLegion"
app.debug?     = true                 # “?” makes the key optional

[database]
driver         = "mysql"
host           = env("DB_HOST", "127.0.0.1")
port           = 3306
name           = "monkeys_app"
user           = env("DB_USER")
pass!          = env("DB_PASS")       # “!” marks as required – missing ⇒ exception

[cache.redis]
host           = "localhost"
port           = 6379
  • Sections are declared with [section], nested via dot-notation.

  • Primitive types: string, int, float, bool, null.

  • Env helper: env(KEY, default?) pulls from $_ENV or putenv().

  • Guards:

    • key! → must exist after env/default merge.

    • key? → optional; missing keys resolve to null.

3 · Loading config in bootstrap

use MonkeysLegion\Mlc\Loader;
use MonkeysLegion\Mlc\Config;

// 1) point the loader at your directory
$loader = new Loader(base_path('config'));

// 2) load one or many files (*.mlc)
$raw    = $loader->load(['app.mlc', 'database.mlc']);

// 3) wrap in an immutable Config object
$config = new Config($raw);

// 4) ask for values anywhere in your code
$dbHost = $config->get('database.host');           // "127.0.0.1"
$isDev  = $config->bool('app.debug');              // true

Config offers helpers for strict casts (string(), int(), array()), default fall-backs (->get('x', 'default')), and guarded retrieval (->require('app.name') throws if absent).

4 · Environment-specific overrides

Directory layout:

config/
├─ app.mlc
├─ database.mlc
└─ env/
   ├─ dev.mlc
   └─ prod.mlc
$env   = $_ENV['APP_ENV'] ?? 'dev';
$raw   = $loader->load(['app.mlc', 'database.mlc', "env/{$env}.mlc"]);
$config= new Config($raw);

Later files override earlier keys, so env/prod.mlc can flip app.debug? = false or point Redis to a different host.

5 · Runtime reloading (CLI & tests)

$config = $config->merge($loader->load('feature-flags.mlc'));

The original object stays untouched; you get a new instance with the extra layer applied—perfect for A/B tests or command-line overrides.

6 · Integration with DI

return [
    MonkeysLegion\Mlc\Config::class => fn () => new Config(
        (new Loader(base_path('config')))->load(['app.mlc', 'database.mlc'])
    ),
];

Any service can now just type-hint Config.

7 · Parser & Loader internals (overview)

  • Parser – tokenises lines, resolves env(), casts primitives, returns nested arrays.

  • Loader – finds files, feeds them to the parser, merges results, detects duplicate keys.

  • Config – read-only wrapper with dot-notation access and merge/cloning helpers.

You rarely touch these classes directly—the façade methods above cover day-to-day needs.

8 · Roadmap

  • Include directive (@include other.mlc) for split configs

  • Hot-reload in DevServer—trigger browser refresh when config/*.mlc changes

  • Validation DSL—define allowable enum values right in the file (mode = enum("dark","light"))

Contributions welcome!

License

MIT © 2025 MonkeysCloud