Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Config Writer Laravel Package

daftspunk/laravel-config-writer

A Laravel package for writing configuration files at runtime. Update config values programmatically and persist them back to your config files with a simple API, so you can manage dynamic settings without editing PHP files by hand. Handy for admin panels and settings screens.

View on GitHub
Deep Wiki
Context7

Getting Started

The package targets one job: modifying PHP config files (the ones that return [ ... ];) in place without wiping comments, ordering, or formatting — unlike the naive File::put(config_path('x.php'), '<?php return ' . var_export($data, true) . ';') approach.

Install:

composer require daftspunk/laravel-config-writer

Register the service provider (skip if you're on Laravel 11+/auto-discovery — the package ships a composer.json extra entry, but verify against the README for your Laravel version):

// config/app.php
Daftspunk\ConfigWriter\ConfigWriterServiceProvider::class,

'aliases' => [
    'ConfigWriter' => Daftspunk\ConfigWriter\Facades\ConfigWriter::class,
],

First write — read the current app.name, replace it, then eyeball the file:

use ConfigWriter;

ConfigWriter::write('app.name', 'Acme Portal');
// config/app.php is rewritten in place; comments and the rest of the array survive.

First use case: an install/setup wizard. You prompt the operator (or an artisan command) for app name, URL, mail driver, and DB credentials, then write them into config/app.php, config/mail.php, and config/database.php. Because the writer preserves the file's structure, the resulting config stays diff-friendly and reviewable — a real win over regenerating the whole file.

Before you write anything else, open the package source and confirm the exact method signatures available in your version (the last release is 2023-08-10). The primary API is write($key, $value) against the default config; a file-targeted variant exists for arbitrary config files — check the README for whether it's write($file, $key, $value) or a separate writeTo($file, $key, $value) method in your installed tag.

Implementation Patterns

Scalar and array writes. Dot-notation keys are used for nested values; arrays are merged into the returned array rather than blown away:

ConfigWriter::write('mail.from.address', '[email protected]');
ConfigWriter::write('mail.from', ['address' => '[email protected]', 'name' => 'Acme']);

Custom file target. For package configs or files outside the default, target the path explicitly (confirm syntax against your installed version — the method name has shifted across releases):

ConfigWriter::write('/path/to/config/settings.php', 'features.beta', true);

Wrap it in a settings repository. Never call ConfigWriter from controllers directly. Put a thin layer in front of it that (a) validates keys against an allowlist, (b) normalises values, and (c) clears the config cache — because the in-memory config loaded at boot is now stale.

class SettingsRepository
{
    public function set(string $key, mixed $value): void
    {
        ConfigWriter::write("settings.{$key}", $value);

        // The running process still holds the old array; drop the cache
        // so the next boot picks up the change.
        Artisan::call('config:clear');
    }
}

Installer / artisan command flow. Build a SetupCommand or a queued installer job that: validates input → backs up the file (File::copy($path, "{$path}.bak")) → writes → runs config:clear → optionally config:cache in production → restarts queue workers with queue:restart. This is the canonical fit for the package and mirrors what WordPress-style wp-config.php installers do.

Feature flags / runtime settings. Keep a dedicated config/settings.php that is only ever written programmatically, not edited by hand. That way you accept the file's formatting churn in one controlled place and keep config/app.php pristine.

Testing. Point config_path() at a fixture directory ($this->app->useConfigPath(__DIR__.'/fixtures/config')), copy a known-good file into it per test, write, and assert against a golden file diff. The whole value proposition is "file integrity," so a diff-based test is the right regression net for a package upgrade.

Gotchas and Tips

  • .env is out of scope. This package rewrites PHP arrays. For environment files you need vlucas/phpdotenv or laravel/envoy-style manual editing — a frequent source of confusion when people install this expecting a universal config writer.
  • config:cache will silently mask your writes. If a cached config exists, booting workers keep the old values regardless of what's on disk. Always clear the cache after a write, and be aware that in a production deployment that has config:cache baked in, your write is effectively a no-op until deploy time. This is the number-one debugging trap.
  • config:clear inside the web request is expensive. Prefer performing writes in a queued job or artisan command so you're not shelling out to a subprocess on every HTTP request.
  • Values must be PHP-literal-serialisable. Strings, ints, floats, bools, null, and nested arrays only. No closures, objects, Carbon, enums, or resources. Enums need explicit ->value. DateTime needs formatting.
  • File permissions. The PHP process must be able to write to config/*.php. In containerised, read-only-image deployments this fails — prefer env vars for runtime config and reserve this package for install-time or admin-triggered changes.
  • No built-in locking. Two concurrent requests writing the same file can corrupt it. Serialise writes: a single queue worker, a Cache::lock(), or an artisan command. Never fire-and-forget from a controller.
  • Back up before writing. The tokenizer is generally well-behaved, but unusual file contents — conditional returns, if (!defined('X')) { ... }, declare(strict_types=1) at the top, or trailing inline comments on the target line — are the cases most likely to produce surprised diffs. Run the writer, git diff the result, and only then trust it in production.
  • Unusual-but-valid syntax can trip the parser. The package re-tokenises and re-renders the array; exotic formatting (heredocs, concatenated string keys, method calls inside the array) may not round-trip. Keep target files plain and boring.
  • New-key insertion position. When the key doesn't yet exist, the package has to decide where to insert it. Verify the resulting layout on first use for each new key; it's likely appended at the end of the returned array rather than in the "logical" place. That's fine, just know it.
  • Pin the version. Last release was August 2023, so the API has been stable for a while but Laravel 11/12 support is worth confirming in CI before adopting. Add "daftspunk/laravel-config-writer": "^1.0" (or whatever the current constraint is) so a future release can't change the file-targeting signature out from under you.
  • Extension point. If the built-in writer can't handle a given file, subclass Daftspunk\ConfigWriter\ConfigWriter and override the token-handling, or simply drop to a safer fallback for that file: read config(), Arr::set(), and File::put(..., '<?php return '.var_export($data, true).';') — accepting the loss of comments as a deliberate trade-off.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib