flamix/settings 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

flamix/settings

Composer 安装命令:

composer require flamix/settings

包简介

Persistent settings in Laravel. Fork from Andreas Lutro app.

README 文档

README

Persistent, application-wide settings for Laravel.

Despite the package name, this package should work with Laravel 8+ (though some versions are not automatically tested).

Installation

  1. composer require flamix/settings
  2. Publish the config file by running php artisan vendor:publish --provider="Flamix\Settings\ServiceProvider" --tag="config". The config file will give you control over which storage engine to use as well as some storage-specific settings.

Usage

You can either access the setting store via its facade or inject it by type-hinting towards the abstract class Flamix\Settings\SettingStore.

<?php
Setting::set('foo', 'bar');
Setting::get('foo', 'default value');
Setting::get('nested.element');
Setting::forget('foo'); // Do not forget save() after this!!
$settings = Setting::all();
?>

Call Setting::save() explicitly to save changes made.

You could also use the setting() helper:

// Get the store instance
setting();

// Get values
setting('foo');
setting('foo.bar');
setting('foo', 'default value');
setting()->get('foo');

// Set values
setting(['foo' => 'bar']);
setting(['foo.bar' => 'baz']);
setting()->set('foo', 'bar');

// Method chaining
setting(['foo' => 'bar'])->save();

Store cache

When reading from the store, you can enable the cache.

You can also configure flushing of the cache when writing and configure time to live.

Reading will come from the store, and then from the cache, this can reduce load on the store.

// Cache usage configurations.
'enableCache' => false,
'forgetCacheByWrite' => true,
'cacheTtl' => 3600,

JSON storage

You can modify the path used on run-time using Setting::setPath($path).

Database storage

Using Migration File

The package migration is loaded automatically — just run php artisan migrate. It creates the settings table (key/value columns by default, names are configurable). Scope columns for setExtraColumns() (e.g. user_id) are not part of this package — the consumer that introduces the scope ships its own migration (in Flamix projects that's ui-saas-user).

Example

For example, if you want to store settings for multiple users/clients in the same database you can do so by specifying extra columns:

<?php
Setting::setExtraColumns([
	'user_id' => Auth::id(),
]);
?>

where user_id = x will now be added to the database query when settings are retrieved, and when new settings are saved, the user_id will be populated.

If you need more fine-tuned control over which data gets queried, you can use the setConstraint method which takes a closure with two arguments:

  • $query is the query builder instance
  • $insert is a boolean telling you whether the query is an insert or not. If it is an insert, you usually don't need to do anything to $query.
<?php
Setting::setConstraint(function($query, $insert) {
	if ($insert) return;
	$query->where(/* ... */);
});
?>

Model storage (default)

The default store is model. It works like the database store, but reads and writes through an Eloquent model instead of a raw connection, so the model defines the table and connection. The model is configured via the SETTINGS_MODEL env variable or the model config key (defaults to Flamix\Settings\Models\Settings).

Scoping works the same way as with the database store:

<?php
// Per-user settings
Setting::setExtraColumns(['user_id' => Auth::id()]);
Setting::set('date_format', 'd.m.Y');
Setting::save();
?>

Note: setExtraColumns() resets the loaded state, so the next read re-queries the store within the new scope. The table needs the extra columns and a composite unique index, e.g. (key, user_id).

Custom stores

This package uses the Laravel Manager class under the hood, so it's easy to add your own custom session store driver if you want to store in some other way. All you need to do is extend the abstract SettingStore class, implement the abstract methods and call Setting::extend.

<?php
class MyStore extends Flamix\Settings\SettingStore {
	// ...
}
Setting::extend('mystore', function($app) {
	return $app->make('MyStore');
});
?>

TODO / Known issues

Prioritized backlog (P0 = most urgent).

P0 — data-loss risks

  • save() does not call load(): after forgetAll() (called directly or implicitly by setExtraColumns()) a save() writes an empty diff and deletes all rows in the current scope. save() must force-load before diffing, and forgetAll() should not mark the store as unsaved (reads currently set unsaved = true via setExtraColumns()).
  • No upsert: write() is a read-modify-write (pluck → update → insert → delete in separate queries). Concurrent requests cause lost updates or unique constraint violations on (key, user_id). Switch to upsert() (available since Laravel 8, which is already the minimum).
  • set($key, null) silently deletes the key: isset() in the write-diff treats null as absent, and nulls are stripped from inserts ("Remove unsupported values"). This is undocumented and inconsistent with get(). Define explicit null semantics.

P1 — bugs & infrastructure

  • ModelSettingStore::parseReadData() references undefined $this->valueColumn in the is_array($row) branch — latent bug, currently masked because Eloquent always returns objects.
  • Tests are broken: they reference the pre-Storages\ namespace, composer.json has no require-dev (no PHPUnit/Mockery), and phpunit.xml targets PHPUnit ≤ 9. Restore the suite (Orchestra Testbench, real DB) and add CI.
  • ServiceProvider::$defer = true was dead code since Laravel 5.8 — dropped $defer/provides(), the provider is intentionally eager: deferral is incompatible with boot-time side effects (loadMigrationsFrom(), publishes()) and saves nothing here.
  • Migrations were both auto-loaded (loadMigrationsFrom()) and publishable — publishing is removed, auto-load only. Scope columns (e.g. user_id) intentionally ship with the consumer package (ui-saas-user), not here — the settings package stays generic key-value.
  • Cache vs scoped reads: cacheKey() concatenates extra-column values only (scopes with different column names but same values collide), and every scoped read goes through setExtraColumns() → full reload, so enabling enableCache produces multiple cache round-trips per read.

P2 — architecture

  • DatabaseSettingStore and ModelSettingStore are ~85% copy-paste (write, forget, prepareInsertData, parseReadData) — extract the shared diff/persist logic (inheritance or trait) so fixes land once.
  • No value serialization: everything is stored as plain text. Arrays survive only via dot-flattening, false becomes '', empty arrays and nulls cannot be stored, types are lost on read. JSON-encode values.
  • No request-level memoization for scoped reads — consumer helpers that fall back from a user scope to the global scope pay two queries per read when the cache is disabled.
  • JsonSettingStore: constructor side effect (created the file inside setPath()) and unlocked writes — the file is now created lazily on the first write and writes use LOCK_EX. Concurrent read-modify-write is still last-write-wins, same as the DB stores until the P0 upsert rework.
  • DatabaseSettingStore::write() carried the Laravel < 5.3 lists/pluck fallback — replaced with a direct pluck() call (the package requires illuminate >= 8, where lists() never exists).

flamix/settings 适用场景与选型建议

flamix/settings 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.35k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 06 月 02 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 flamix/settings 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 flamix/settings 我们能提供哪些服务?
定制开发 / 二次开发

基于 flamix/settings 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.35k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 112
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-06-02