honeystone / context
Laravel的应用上下文管理器。
Requires
- php: ^8.1
- illuminate/contracts: ^10.0|^11.0
- spatie/laravel-package-tools: ^1.16.4
Requires (Dev)
- nunomaduro/collision: ^8.0
- nunomaduro/larastan: ^2.9
- nunomaduro/phpinsights: ^2.11
- orchestra/testbench: ^9.2
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.4
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^1.2
- phpstan/phpstan-phpunit: ^1.4
- phpunit/phpunit: ^10.0
- spatie/laravel-ray: ^1.37
This package is auto-updated.
Last update: 2024-09-26 22:14:42 UTC
README
我们开发了honeystone/context
,用于管理多租户应用中的应用上下文。它提供了一个简单、流畅的API,用于通过'上下文解析器'初始化、扩展和切换上下文。此外,上下文在队列作业中自动可用,并且可以用于限定Eloquent模型。
这个包几年前是为我们自己的多租户应用开发的。我们最近决定将其发布,希望它对更广泛的Laravel社区有用。我们欢迎贡献、反馈和建设性的批评。
入门
首先阅读简要博客文章,该文章演示了如何在多租户应用中使用此包。
支持我们
我们致力于提供由Honeystone团队维护的高质量开源包。如果您想支持我们的努力,只需使用我们的包、推荐它们并做出贡献。
如果您在项目中需要任何帮助,或需要任何定制开发,请联系我们。
安装
composer require honeystone/context
使用
一个典型的用例是在您的中间件中声明和初始化上下文。然后您可以像这样访问上下文数据
$team = context('team'); $project = context('project');
定义上下文
在解析之前需要定义上下文
context()->define() ->require('team', Team::class) ->require('project', Project::class);
这些上下文定义是'必需的',因此如果它们无法解析,将会抛出CouldNotResolveRequiredContextException
异常。对于未定义的上下文,将抛出UndefinedContextException
异常。
您还可以定义'接受的',但不是'必需的'上下文
context()->define() ->accept('team', Team::class) ->accept('project', Project::class);
或者根据其他上下文的存在来接受/要求
context()->define() ->require('team', Team::class) ->requireWhenProvided('team', 'project', Project::class); //Or acceptWhenProvided
初始化上下文
要初始化上下文,您需要提供一个解析器
context()->initialize(new MyResolver());
以下是一个示例解析器类
<?php declare(strict_types=1); namespace App\Context\Resolvers; use Honeystone\Context\ContextResolver; class MyResolver extends ContextResolver { public function __construct( private ?Team = null, private ?Project = null, ) {} public function resolveTeam(): Team { //your resolution logic return $this->team; } public function resolveProject(): Project { //your resolution logic return $this->project; } public static function deserialize(array $data): static { //you must also declare a deserialization method, //to reinstate the serialised data return new static($team, $project); } }
您可以根据这种方式自定义序列化逻辑
class MyResolver extends ContextResolver { //... public function serializeTeam(Team $team): int { return $team->id; } }
您可以根据这种方式验证解析上下文的完整性
class MyResolver extends ContextResolver { //... public function checkProject( DefinesContext $definition, Project $project, array $resolved, ): bool { return $project->id === $resolved['team']->project_id; } }
您还可以重新初始化或注销当前上下文
context()->reinitialize(new AnotherResolver()); context()->deinitialize();
扩展上下文
可以使用另一个解析器扩展当前上下文
context()->define()->accept('site', Site::class); context()->extend(new AnotherResolver());
临时切换上下文
使用闭包
context()->initialize(new MyResolver()); context()->temporarilyInitialize(new AnotherResolver()) ->run(function () { //do something });
使用start和end方法
context()->initialize(new MyResolver()); $tmpContext = context()->temporarilyInitialize(new AnotherResolver()); $tmpContext->start(); //do something $tmpContext->end();
事件和接收器
Honeystone\Context\Events\ContextChanged
事件在上下文更改时发出。
您还可以指定当设置单个上下文值时通知的接收器
context()->receive('team', new MyReceiver());
以下是一个示例接收器
<?php declare(strict_types=1); namespace App\Context\Receivers; use Honeystone\Context\Contracts\ReceivesContext; class TeamReceiver implements ReceivesContext { public function receiveContext(string $name, ?object $context): void { //process received context } }
使用上下文限定模型
您可以使用当前上下文来限定您的Eloquent模型。
以下是一个示例
<?php declare(strict_types=1); namespace App\Models; use Honeystone\Context\Models\Concerns\BelongsToContext; use Illuminate\Database\Eloquent\Model; class Project extends Model { use BelongsToContext; protected static array $context = ['team']; //optionally specify context aliases protected static array $context = ['team' => 'my_team']; //optionally configure a context foreign key protected function getTeamContextForeignKey(Team $team): string { return 'my_team_id'; //the default is generated like this } //optionally configure a context owner id protected function getTeamContextOwnerId(Team $team): int { return $context->id; //defaults to the id prop } //optionally configure the relationship name protected function getTeamContextRelationName(Team $team): string { return 'my_team'; //the default is generated like this } }
已知问题
- 测试需要改进
Laravel的"上下文"
当创建此解决方案时,Laravel上下文不存在。函数名冲突是不幸的,但并不是真正的问题。您只需确保导入该函数。
use function Honeystone\Context\context;
尽管名称会邀请比较,但这些包解决的是不同的问题。Laravel上下文是一个通用的全局数据存储。这个包专门用于解决具有更复杂逻辑的上下文对象,并使用它们来限定应用,例如在多租户应用中。
变更日志
更改列表可以在CHANGELOG.md文件中找到。