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

Setting Laravel Package

ibrand/setting

A Laravel settings package for storing and managing application configuration in the database. Organize values into groups, cache them for fast access, and read or update settings anywhere via simple helper functions.

View on GitHub
Deep Wiki
Context7

Getting Started

ibrand/setting is a small key/value settings store backed by a database table, plus a helper/facade for reading and writing those values. It solves one job: persist admin-editable configuration (site name, logo path, feature flags, support email) without shipping a new deploy.

  1. Install

    composer require ibrand/setting
    

    On Laravel 5.5+ the service provider should be auto-discovered; on older versions register Ibend\Setting\SettingServiceProvider in config/app.php and add the Setting facade alias.

  2. Publish and migrate

    php artisan vendor:publish --provider="Ibend\Setting\SettingServiceProvider"
    php artisan migrate
    

    This is where most people trip up first: the package ships a migration, but if you only register the provider and never publish/migrate, setting() will throw "table not found" on first call.

  3. Look first at

    • README.md — the exact method signatures (get, set, has, all, forget) and whether the helper is setting() or facade-only.
    • The published migration — column names (key/name, value) drive everything below.
    • The service provider — confirms caching behaviour and whether it binds a singleton.
    • The v1.2.0 diff — the release removed unused code and reworked the hot read path, so confirm any method you were relying on still exists.
  4. First real use case — a "Site Settings" admin page:

    // read with a sane default
    $siteName = setting('site.name', config('app.name'));
    
    // write from a controller
    setting(['site.name' => $request->input('name')]);
    

    Verify the exact API in the README; the helper may be setting('key') for get and setting(['key' => 'value']) for set, or a facade such as Setting::get() / Setting::set().

Implementation Patterns

Namespaced dotted keys. Treat the key column like a flat config tree: site.name, site.logo, mail.from, features.registration. It keeps all() readable and lets you scope reads (site.*) without a schema change.

Config fallback at the call site. Don't bury defaults in the DB. Keep config/*.php as the source of truth and let the DB override:

$from = setting('mail.from', config('mail.from.address'));

This means a fresh install works before anyone has opened the settings page.

Write-through with a repository. Wrap reads/writes in a small SettingsService so the rest of the app depends on your class, not the package. That is your escape hatch if you later migrate to spatie/laravel-settings:

class Settings
{
    public function get(string $key, $default = null) { return setting($key, $default); }
    public function put(array $values): void { setting($values); }
}

Bulk set from forms. Settings pages usually submit a group at once. One setting([...]) call (or a loop) is fine — the package writes row-by-row, so wrap it in a transaction if you need atomicity.

Cache on read, bust on write. In practice settings are read on nearly every request. The v1.2.0 "optimize performance based on usage issue" change targets exactly this path, but don't assume it made caching correct on its own — verify the provider and, if needed, cache yourself:

$settings = Cache::rememberForever('settings.all', fn () => setting()->all());

and forget the key whenever you write.

Blade and views. Keep the helper for view convenience ({{ setting('site.name') }}), but pass values down from controllers for anything non-trivial so views aren't hitting the DB/cache indirectly.

Typed values. Settings are usually stored as strings. If the README shows array/JSON support, use it for lists (social links, nav items); otherwise serialize explicitly and cast on read:

setting('features.json', json_encode($flags));
$flags = json_decode(setting('features.json'), true);

Testing. Use RefreshDatabase and seed the keys you need per test; don't assume production rows exist.

Gotchas and Tips

  • Table-not-found is the #1 error. If setting() fails after composer require, you forgot vendor:publish + migrate. Confirm the migration actually ran (php artisan migrate:status).
  • Caching across servers. If the package caches in-process or in the Laravel cache, a write on one web node won't invalidate another node's cache. Use a shared cache store (Redis) or clear on deploy.
  • null vs false vs empty string. A naive get() implementation returns the default when the stored value is falsy, so a stored 0 or false can silently become your default. Store booleans as "0"/"1" and test the round-trip.
  • No type casting by default. Everything comes back as a string. Cast at the boundary ((bool), (int), json_decode) rather than sprinkling casts through views.
  • Key collisions. Without a namespace convention, name gets reused for the site name, the user's name, and the product name. Adopt dotted keys from day one; renaming later requires a data migration.
  • Array/object serialization. If you store arrays, confirm how the package serializes them (PHP serialize vs json_encode) and don't mix the two — old rows will break json_decode.
  • Mass-write pitfalls. setting($request->all()) lets a request write arbitrary keys (e.g. app.debug). Whitelist the fields you accept.
  • Small, low-activity package. The 1.x line is now at v1.2.0, a maintenance release (dead-code removal + a read-path performance tweak) rather than a feature release; the ecosystem around it is still tiny (no meaningful dependents). Treat it as "occasionally touched", not "actively developed": pin the version, and since the dead-code cleanup could have dropped a rarely-used public method, re-read the diff before upgrading from an older 1.x. There are still no Laravel 10/11 guarantees and no security-patch cadence. If you need maintained first-class support (typed settings classes, casts, encryption), budget for spatie/laravel-settings — the SettingsService wrapper above makes that swap a one-file change.
  • Extension points. The service provider is small; you can rebind the underlying model/repository in a custom provider to add encryption, auditing, or per-tenant scoping without forking the package.
  • Debugging. When a value "doesn't stick," check in this order: the migration table exists, the cache was invalidated, the key string matches exactly (trailing spaces!), and the stored type matches what your read code expects. After the v1.2.0 read-path change, also re-check that a warm cache still reflects a write made in the same request cycle — a classic regression in performance-focused releases.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings