Configuration
Lunaris keeps configuration in two places: a .env file for secrets and environment values, and a single PHP array in config/vars.php for everything else.
The .env file
Environment variables are loaded at boot with vlucas/phpdotenv in
immutable mode. Keys are read through the env() helper — never through
$_ENV or getenv() directly.
APP_KEY=def0000042cec0... # Defuse ASCII-safe key (php lunar key:generate)
APP_NAME="Lunaris"
APP_URL=http://lunaris
config/vars.php
The central configuration file returns an array. Values may be
closures, which are evaluated lazily when read — this is how config
values wrap env() calls without paying for them on every request.
<?php
return [
"app" => [
"key" => fn() => env("APP_KEY", ""),
"version" => fn() => env("APP_VERSION", "1.0.0"),
"name" => fn() => env("APP_NAME", "Lunaris"),
],
"errors" => [
"notfound" => fn() => env("ERROR_NOT_FOUND", null),
"forbidden" => fn() => env("ERROR_FORBIDDEN", null),
"exception" => fn() => env("ERROR_EXCEPTION", null)
],
];
Reading configuration
Config values are read with dot notation through the config() helper:
config("app.name"); // "Lunaris" (from APP_NAME or default)
config("app.key"); // the APP_KEY value
config("errors.notfound"); // custom 404 page, or null
If a value is null, or the key path doesn’t exist, the default is returned:
config("app.missing", "fallback"); // "fallback"
The env() helper
env("APP_NAME", "Lunaris"); // value of APP_NAME, or "Lunaris" if unset/empty
Drop a new entry into config/vars.php — keep wrapping
env() in a closure so the value stays lazy:
"stripe" => ["key" => fn() => env("STRIPE_KEY")], then read it with
config("stripe.key").
Global helpers
All helpers live in system/funcs.php and are autoloaded globally:
| Helper | Description |
|---|---|
env($key, $default) | Read an environment variable (empty/unset → $default). |
config($key, $default) | Read a config value with dot notation. |
path() / base_path($path) | The registered project root / a root-anchored path. |
server() | Origin URL scheme://host from a validated HTTP_HOST; honors X-Forwarded-Proto. |
asset($path) | Full URL to a file under public/. |
url() | Fully-qualified URL of the current request. |
response() | A new System\Http\Response instance. |
route($name, $params) | Generate a URL from a named route (or the current route name with no args). |
route_is($route) / route_in([...]) | Current-route checks. |
notfound($msg) / forbidden($msg) / error($msg) | Throw the matching LunarException. |
csrf_field($name) | Hidden input carrying the CSRF token (for forms). |
isfile($value) | True if $value is a valid HTTP upload. |
Helper examples
asset("logo.png"); // http://localhost:8080/logo.png
url(); // http://localhost:8080/current/path
base_path("config"); // <project root>/config
// validated, trusted origin only
server(); // "http://localhost:8080"
server() only trusts the host if it matches a hostname regex, and only
honours X-Forwarded-Proto when it is literally http or
https. Don’t build origin URLs from raw headers yourself.
Part of the Lunaris documentation · Source on Codeberg · MIT License