ralphjsmit / laravel-helpers
一个包含方便的助手函数的Laravel应用包。
Requires
- php: ^8.0
- guzzlehttp/guzzle: ^7.4
- illuminate/contracts: ^8.73|^9.0|^10.0|^11.0
- spatie/laravel-package-tools: ^1.9.2
Requires (Dev)
- livewire/livewire: ^2.9|^3.4
- nesbot/carbon: ^2.66|^3.0
- nunomaduro/collision: ^5.10|^6.1|^7.0|^8.0
- orchestra/testbench: ^6.22|^7.0|^8.0|^9.0
- pestphp/pest: ^1.21|^2.34
- pestphp/pest-plugin-laravel: ^1.1|^2.3
- phpunit/phpunit: ^9.5|^10.5
- spatie/invade: ^1.0|^2.0
- spatie/laravel-ray: ^1.26
README
此包包含了一组方便的助手函数,用于您的Laravel应用。
安装
您可以通过composer安装此包
composer require ralphjsmit/laravel-helpers
Laravel
工厂
您可以让您的工厂扩展Laravel默认的工厂,也可以让它们扩展RalphJSmit\Helpers\Laravel\Factories\Factory
类。
使用resolveRelationship()
进行复杂的工厂关系
当您有一个复杂的关系时,您可以使用resolveRelationship()
方法来解决这个关系。如果您想使用闭包或类似的方式来修改工厂,这非常有用。
use RalphJSmit\Helpers\Laravel\Factories\Factory; class PostFactory extends Factory { public function definition(): array { return [ 'user_id' => null, ]; } public function withUser(User|UserFactory|Closure|int|null $user = null): static { return $this->set('user_id', $this->resolveRelationship(User::class, $user)); } }
一个简单的例子可能如下所示
$post = Post::factory() ->withUser(fn(UserFactory $factory): UserFactory => $factory->set('name', 'John Doe')) ->create();
管道,流水线 & 可管道
管道与流水线
Laravel有一个未记录的功能叫做流水线。流水线非常适合将数据通过一系列的函数/类发送。
然而,Laravel中的流水线有一个很大的缺点:在每一个函数或类中,您需要调用一个闭包来移动到流水线中的下一个管道。如果您不调用这个闭包,流水线就会停止。Laravel中间件就是一个很好的例子。
但是,有时您可能不想使用闭包,只想将第一个管道的结果传递给第二个管道,这意味着整个流水线总是会被执行。此包为此提供了一个自定义实现,称为“管道”。您没有停止执行的方法(请使用常规流水线),但您也不需要在每个管道中调用闭包。
从现在起,我将把这个包的自定义实现称为“管道”,而将更高级的、常规的Laravel实现称为“流水线”。
流水线
您可以使用pipeline()
函数创建一个新的流水线
$result = pipeline() ->send($class) ->through($pipes) ->thenReturn();
要了解更多关于流水线的信息,请查看这篇文章。
管道
您可以使用pipe()
函数创建一个新的管道
$result = pipe($thing) ->through([ PerformAction::class, PerformAnotherAction::class, ]) ->then(function($result) { // Do something with $result and return it. return $result; });
->through()
数组中的每个项目可以是以下之一
- 一个闭包或可调用对象
- 一个可调用的类(它也是一个可调用对象)
- 一个类实例
- 一个类字符串
默认情况下,管道将尝试通过方法'handle'来执行每个项目。您可以使用->via()
方法来更改该方法。
在每个管道的末尾,您可以将一个闭包传递给->then()
方法来对结果进行处理。您也可以使用->thenReturn()
方法立即返回结果。
$result = pipe($thing) ->through(/** */) ->via('execute') ->thenReturn();
可管道
此包还提供了一个方便的特性,您可以使用它来使您的类可管道。如果您包含此特性,您的类将具有以下新方法
->pipe($callback)
。此方法将对象传递给给定的闭包或可调用对象,并返回执行的可调用对象的结果。->pipeInto($class)
。此pipeInto()
方法创建给定类的新实例,并将对象传递给构造函数。->pipeThrough($callbacks)
。此pipeThrough()
方法将对象传递给给定的闭包/可调用对象数组,并返回执行的可调用对象的结果。
所有三种方法都与 \Illuminate\Support\Collection
类中同名的方法相同。例如,请参阅 Laravel 网站上关于 pipe()
、pipeInto()
和 pipeThrough()
的文档。
Carbon
此包提供了一些方便的辅助函数,使使用 Carbon 对象更加愉快。
carbon($input = null, $timezone = null)
您可以使用 carbon($input, $timezone)
辅助函数来创建一个 Carbon 对象。在底层,这使用 Carbon::parse()
。两个参数都是可选的。
$firstDayOfNextMonth = carbon('first day of next month', 'Europe/Amsterdam');
carbonDate($input = null, $timezone = null)
您可以使用 carbonDate($input, $timezone)
辅助函数来创建一个 Carbon 对象,并将天.floor() 到 00:00:00。底层使用 Carbon::parse()->floorDay()
。两个参数都是可选的。
$firstDayOfNextMonth = carbonDate('first day of next month', 'Europe/Amsterdam'); $firstDayOfNextMonth->toTimeString(); // '00:00:00'
yesterday()
和 tomorrow()
您可以使用 tomorrow()
函数创建明天的 Carbon 实例。底层使用 now()->addDay()
。
您可以使用 yesterday()
函数创建昨天的 Carbon 实例。底层使用 now()->subDay()
。
$tomorrow = tomorrow(); $yesterday = yesterday();
daysOfMonth(Carbon|string $month)
您可以使用 daysOfMonth()
函数创建一个 Collection
实例,其中月份的日期作为数字键,值为 0
。这对于创建图表等非常有用。
$days = daysOfMonth(carbon('march 2021')); $days->all(); // [ // 1 => 0, // 2 => 0, // 3 => 0, // 4 => 0, // 5 => 0, // ... // 30 => 0, // 31 => 0, // ]
Eloquent
TimeCast
Eloquent 提供了许多有用的类型转换,如 array
、date
和 datetime
。然而,Laravel 并没有提供 time
类型转换,用于存储和转换如 "08:30:00" 这样的时间戳到 Carbon 实例。
原因可能是因为仅传递 "08:30:00" 这样的时间戳到 Carbon 假设了一个带有当前日期的 Carbon 实例。这可能会或可能不会成为您的问题。
为了将时间字符串转换为 Carbon 实例,您可以将 TimeCast
类设置为类型转换。但请注意,这将创建一个假设当前日期的 Carbon 实例。
use RalphJSmit\Helpers\Laravel\Models\Casts\TimeCast; class Something extends Model { protected $casts = [ 'time' => TimeCast::class, ]; };
BooleanAsTimestampCast
BooleanAsTimestampCast
类型转换是一个方便的类型转换,您可以使用它将布尔值存储为时间戳。实际上,这仍然与数据库中的普通布尔值一样工作。但是,以这种方式存储布尔值可以为您提供额外的优势,即知道布尔值何时启用。
如果值设置为 true
,它将在数据库中存储当前的时间戳。如果值设置为 false
,它将在数据库中存储 null
。
use RalphJSmit\Helpers\Laravel\Models\Casts\TimeCast; class Something extends Model { protected $casts = [ 'time' => BooleanAsTimestampCast::class, ]; };
#### Smart factory name guessing with `HasFactory` You can use the new `HasFactory` trait to automatically guess the name of your factories. This optimized factory trait can also guess the name of factories in different namespaces than `App\Models`, like `Support\. ```php use Illuminate\Database\Eloquent\Model; use RalphJSmit\Helpers\Laravel\Concerns\HasFactory; class MyModel extends Model { use HasFactory; }
如果您需要或希望自行定义工厂类,您还可以使用 protected $factory
属性来定义您的工厂。
class MyModel extends Model { use HasFactory; protected $factory = MyModelFactory::class; }
Livewire
CanBeRefreshed 特性
您可以使用 CanBeRefreshed
特性来自动注册以下事件
use RalphJSmit\Helpers\Livewire\CanBeRefreshed; class MyComponent extends Component { use CanBeRefreshed; // Will register the following event and listener: // [ '$refresh' => '$refresh', ] // Registering additional listeners is no problem: protected $listeners = [ /* Your other listeners */ ]; }
RegisterListeners 特性
您可以使用 RegisterListeners
特性动态注册事件监听器,例如从 mount()
或 initialized()
方法中。
use RalphJSmit\Helpers\Livewire\RegisterListeners; // Somewhere... $this->registerListeners([ 'my-event' => 'myListener' ]);
RegisterMessages 特性
您可以使用 RegisterMessages
特性动态注册事件监听器,例如从 mount()
或 initialized()
方法中。
use RalphJSmit\Helpers\Livewire\RegisterMessages; // Somewhere... $this->registerMessages([ 'user.email.required' => 'Adding an e-mail address is required.' ]);
通用
🐞 如果您发现一个错误,请提交详细的问题,我会尽快修复。
🔐 如果您发现一个漏洞,请查看 我们的安全策略。
🙌 如果您想贡献,请提交拉取请求。所有 PR 都会得到完全的认可。如果您不确定我是否会接受您的想法,请随时联系我!
🙋♂️ Ralph J. Smit