dive-be / laravel-feature-flags
在您的 Laravel 应用中处理功能标志
Requires
- php: ^8.1
- illuminate/auth: ^9.0
- illuminate/cache: ^9.0
- illuminate/console: ^9.0
- illuminate/contracts: ^9.0
- illuminate/database: ^9.0
- illuminate/events: ^9.0
- illuminate/http: ^9.0
- illuminate/support: ^9.0
- illuminate/view: ^9.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.6
- nunomaduro/larastan: ^2.0
- orchestra/testbench: ^7.0
- pestphp/pest: ^1.21
- pestphp/pest-plugin-laravel: ^1.2
- phpunit/phpunit: ^9.5
- spatie/laravel-translatable: ^5.2
Suggests
- spatie/laravel-translatable: Required for defining messages for multiple locales
README
请使用更好的替代方案
此包解决了什么问题?
"功能标志是一种软件开发流程,用于在不部署代码的情况下远程启用或禁用功能。新功能可以部署而不使其对用户可见。功能标志有助于解耦部署和发布,让您管理功能的整个生命周期。"(来源:https://launchdarkly.com/blog/what-are-feature-flags)
安装
您可以通过 composer 安装此包
composer require dive-be/laravel-feature-flags
一旦 composer 完成,您必须发布配置和迁移
php artisan feature:install
这是已发布配置文件的內容
return [ /** * The name of the cache key that will be used to cache your app's features. */ 'cache_key' => 'feature_flags', /** * The feature model that will be used to retrieve your app's features. */ 'feature_model' => Dive\FeatureFlags\Models\Feature::class, ];
如果您不需要多语言支持,您现在就可以开始了。
多语言支持
此包使用 Spatie 的优秀 Laravel 可翻译包 提供一流的多语言支持。
composer require spatie/laravel-translatable
接下来,转到配置文件并将 feature_model
更改为
Dive\FeatureFlags\Models\TranslatableFeature::class
最后,找到迁移并取消注释注释,并删除其前面的所有内容。它应该如下所示
// ... $table->json('message')->nullable(); $table->timestamp('disabled_at')->nullable(); // ...
使用方法
有关您可用的完整列表,请参阅 功能合约 以获取详尽列表。
设置您的应用初始功能
可以在常规 Laravel 种子中进行(初始)功能的播种。
php artisan make:seeder FeaturesTableSeeder
以下是一个示例
use Dive\FeatureFlags\Models\Feature; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; class FeaturesTableSeeder extends Seeder { public function run() { DB::table('features')->upsert([ [ 'description' => 'Registrations that come through our partnerships', 'label' => 'Public registrations', 'message' => 'The registration period has ended. Thanks for participating in our programme.', 'name' => 'registrations', 'scope' => Feature::getDefaultScope(), ], [ 'description' => 'Display the App version on the homepage', 'label' => 'Application version', 'message' => 'Version is hidden', 'name' => 'version', 'scope' => Feature::getDefaultScope(), ], ], ['scope', 'name'], ['description', 'label', 'message']); } }
解析管理器
此包提供了从 IoC 容器中解析 Feature
实例的每一种可能方式。我们为您做好了准备!
外观
use Dive\FeatureFlags\Facades\Feature; Feature::find('dashboard');
或者使用别名(特别有助于 Blade 视图)
use Feature; Feature::disabled('dashboard');
辅助函数
feature('dashboard'); feature_disabled('dashboard'); feature_enabled('dashboard'); feature_verify('dashboard');
依赖注入
use Dive\FeatureFlags\Contracts\Feature; public function index(Feature $feature) { $feature->verify('dashboard'); return view('layouts.dashboard'); }
服务定位
app('feature')->find('dashboard');
范围
此包允许您定义一个自定义范围,并将其与功能(不要与 Laravel 的全局范围混淆)一起使用。特别适用于您需要为应用程序的不同部分使用相同名称时。此包的大部分函数和方法都接受一个额外的 $scope
参数。
请参阅功能合约以获取完整列表。
更改默认通配符作用域
如果您希望使用除默认的星号(*)以外的不同作用域来创建和检查/验证功能,您可以在AppServiceProvider
的boot
方法中更改此设置。
use Dive\FeatureFlags\Models\Feature; class AppServiceProvider extends ServiceProvider { public function boot() { Feature::setDefaultScope('my-wonderful-app'); } }
种子
有关如何设置功能的作用域,请参阅上面的种子部分。
Blade指令 🗡
@disabled
您可以使用@disabled
指令根据功能的当前状态有条件地在视图中显示内容。使用此指令首先将使功能的message
属性自动成为块内作用域变量。示例
@disabled('registrations') <div class="alert warning"> {{ $message }} <!-- Automatically injected --> </div> @enabled <div class="alert info"> Welcome to our public registrations. </div> @enddisabled
@enabled
您还可以使用@enabled
指令执行与上面相同的事情。但是,使用此指令首先时,$message
变量将不可用于@disabled
块内。
@enabled('registrations') <div class="alert info">text</div> @disabled <div>$message is not available here</div> @endenabled
@can(not)
此包还注册了自己在Laravel的Gate上。访客不需要认证即可使用它。
@can('feature', 'dashboard') <a href="/dashboard" target="_blank">View Dashboard</a> @else <small>Dashboard is currently disabled</small> @endcan
保护应用程序的部分 💂🏼
有多种方法可以防止用户访问应用程序中禁用的部分。
如果功能未启用,将抛出FeatureDisabledException
。
路由中间件
Route::get('registrations', [RegistrationsController::class, 'index'])->middleware('feature:registrations');
使用 'verify' 手动检查
控制器示例
假设您典型的控制器
class RegistrationsController extends Controller { public function __construct(Feature $feature) { $feature->verify('registrations'); } public function index() { return view('registrations.index'); } }
Livewire示例
这在无法真正使用路由中间件的环境中特别有用,例如Livewire操作。
use Dive\FeatureFlags\Facades\Feature; use Dive\Wishlist\Facades\Wishlist; class HeartButton extends Component { public function add($id) { Feature::verify('wishlist'); Wishlist::add($id); } public function render() { return view('livewire.heart-button'); } }
PS:别忘了检查我们的愿望单包哦😉
访问门
此包还注册了自己在Laravel的Gate上,提供您通过它们检查功能状态的能力。这意味着您可以执行如下操作
Route::get(...)->middleware('can:feature,dashboard');
Gate::authorize('feature', 'dashboard');
然而,有一个关键的区别。Laravel的Gate将抛出AccessDeniedHttpException
,而包自身的检查将抛出FeatureDisabledException
(它扩展了前者异常类)。因此,如果您需要知道异常的类型,强烈建议您不要使用门。
Artisan命令 🧑🎨
切换功能的开关
由于功能是通过Feature
Eloquent模型管理的,因此您当然可以使用像Laravel Nova这样的解决方案来完成此操作。
然而,在本地开发时,您可能希望轻松地打开/关闭某个功能。您可以使用以下命令来完成此操作
php artisan feature:toggle {name} {scope?}
显示所有功能的列表
使用以下命令显示所有功能和它们对应状态的表格
php artisan feature:list
可用选项:compact
、disabled
、enabled
、scope
。
清除缓存
功能被永久缓存以加快后续检查。如果您不使用Eloquent来更新或修改记录,您必须手动重置缓存
php artisan feature:clear
注意:通过Eloquent创建/更新功能时,缓存清除会自动为您完成。
测试
composer test
变更日志
请参阅CHANGELOG以获取有关最近更改的更多信息。
贡献
请参阅CONTRIBUTING以获取详细信息。
安全
如果您发现任何安全相关的问题,请通过电子邮件oss@dive.be联系,而不是使用问题跟踪器。
鸣谢
许可
MIT 许可证(MIT)。请参阅许可文件以获取更多信息。