Try it yourself

🔄

Clone this demo locally from github.com/HPWebdeveloper/laravel-env-setting-demo, then change APP_ENV in your .env file (e.g. to staging or production), run php artisan config:clear, and refresh this page to see every value change automatically.

Current APP_ENV: production

AI Settings (AiSettings)

provider openai
text_model gpt-4o
embeddings_model text-embedding-3-large
max_tokens 8000
temperature 0.2

Payment Settings (PaymentSettings)

mode live
currency USD
retry_attempts 5
webhook_url https://app.example.com/webhooks/payments

Notification Settings (NotificationSettings)

sms_provider vonage
sms_from +15559876543
default_channel sms
rate_limit_per_minute 200
sandbox_mode false

External API Settings (ExternalApiSettings)

billing_service_url https://billing.internal
inventory_service_url https://inventory.internal
notification_service_url https://notify.internal
timeout 10
retry_attempts 5

Root App Settings (AppSettings)

What is this? Instead of accessing each settings class individually (AiSettings, PaymentSettings, etc.), you can create a single root settings object that groups them all together.

AppSettings is a settings class whose properties are other settings classes. When it resolves for the current environment, it calls each sub-setting's environment method internally — so you get one object that holds the full configuration tree.

Usage: envSettings(AppSettings::class)->ai->text_model or envSettings(AppSettings::class)->payment->mode — access any nested setting from a single entry point.

Full JSON output of the composed settings tree for the current production environment:

{
    "ai": {
        "provider": "openai",
        "text_model": "gpt-4o",
        "embeddings_model": "text-embedding-3-large",
        "max_tokens": 8000,
        "temperature": 0.2
    },
    "payment": {
        "mode": "live",
        "currency": "USD",
        "retry_attempts": 5,
        "webhook_url": "https:\/\/app.example.com\/webhooks\/payments"
    },
    "notification": {
        "sms_provider": "vonage",
        "sms_from": "+15559876543",
        "default_channel": "sms",
        "rate_limit_per_minute": 200,
        "sandbox_mode": false
    },
    "external_api": {
        "billing_service_url": "https:\/\/billing.internal",
        "inventory_service_url": "https:\/\/inventory.internal",
        "notification_service_url": "https:\/\/notify.internal",
        "timeout": 10,
        "retry_attempts": 5
    }
}

Helper vs Singleton Identity

What does this prove? There are two ways to get a settings instance in Laravel:

  1. Helper function: envSettings(AiSettings::class)
  2. Type-hinted injection: public function __invoke(AiSettings $ai) in a controller

Because this package registers each settings class as a singleton in Laravel's service container, both approaches return the exact same object in memory — not a copy, not a new instance, but the same one.

This means you can freely mix both styles in your application without worrying about inconsistent state or wasted memory.

envSettings(AiSettings::class) and a type-hinted AiSettings injection resolve to the same singleton instance: yes — same instance

Get Started — Installation & Usage Guide