Siu Ho @ This is the ninth article
Long time no update articles, and said the result was a good week more time is their own arrangements for the defeated. . . .
Today, we introduce is in
Laravel
how to use and flexibleTrait
, talking aboutTrait
, I started not know what kind of existence, there is a vague impression is: reuse. Has always been the understanding of the use and reuse of is this: write in a public class, where the need to call where the purpose is less to write some code, ha ha.Ado, now.
Foreword
You may often see the following situations:
class Post extends Model
{ protected static function boot() { parent::boot(); static::saving(function ($post){ $post->creator_id = $post->creator_id ?? \auth()->id(); }); } } // 或者 class Video extends Model { protected static function boot() { parent::boot(); static::saving(function ($post){ $post->creator_id = $post->creator_id ?? \auth()->id(); }); } } // 或者直接在控制器中指定 creator_id
We can see, the code is clearly repeated, but in the end how separated achieve reuse it.
such?
public function hasCreator($model) { $model->creator_id = $model->creator_id ?? \auth()->id(); } // 封装一个上述公共方法,然后在模型中调用,或者在控制器中调用。
We found that these operations are not very good, not elegant, ha ha. From the example above Now we look at laravel
the Trait
how is defined and used:
// 定义
trait HasCreator
{
public static function bootHasCreator() { static::saving(function ($model) { $model->creator_id = $model->creator_id ?? \auth()->id(); }); } } // 调用 class Post extends Model { use HasCreator; } // 可以了,哈哈,自动调用已经可以实现对 creator_id 的自动写入了,是不是很优雅,哈哈。
Now explain step by step how to write.
Start
The official explanation: Trait is a mechanism for code reuse single inheritance language similar to PHP's prepared. Trait In order to reduce single inheritance language restrictions, allowing developers to freely separate class multiplexing method in a different hierarchy. Trait semantic definitions and combinations of Class A way to reduce complexity, avoid the traditional typical problems and multiple inheritance classes Mixin related. .
-
First we have to know how to define a
Trait
keyword is usedtrait
instead ofclass
namespace App\Traits; trait HasCreator { }
-
Define methods (we start with a simple to)
namespace App\Traits; trait HasCreator { public static function hasCreator() { static::saving(function ($model) { $model->creator_id = $model->creator_id ?? 1; }); } }
It can be seen in
Trait
the declaration of asetCreator
method, which is still therecreator
to set the default value -
transfer
namespace App; use App\Traits\HasCreator; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Post extends Model { use HasCreator, SoftDeletes; protected $fillable = ['title', 'user_id']; protected static function boot() { parent::boot(); self::hasCreator(); } }
With my understanding it is to
Trait
the methods incorporated into the model to go, in order to use ituse
a bit, and then when as like to call their own declaration.
We can also see the example above use
the SoftDeletes
, let's simply look at its source code:
namespace Illuminate\Database\Eloquent; trait SoftDeletes { /** * Indicates if the model is currently force deleting. * * @var bool */ protected $forceDeleting = false; /** * Boot the soft deleting trait for a model. * * @return void */ public static function bootSoftDeletes() { static::addGlobalScope(new SoftDeletingScope); } /** * Force a hard delete on a soft deleted model. * * @return bool|null */ public function forceDelete() { $this->forceDeleting = true; return tap($this->delete(), function ($deleted) { $this->forceDeleting = false; if ($deleted) { $this->fireModelEvent('forceDeleted', false); } }); } ...... }
We can see from the source code display, the current Trait
definition of a property, two methods can actually define properties, it is not very unexpected, ha ha.
You might ask, if Task
also defines the $forceDeleting
attributes how to do, which dominated it, there actually has a priority: call the class> Trait> parent, that appeared to duplicate the properties and calling class when Trait in time method, the default is the calling class-based.
Next we look at the following two methods:
bootSoftDeletes
: Static prefix plus the boot, which means Shane? It represents the default action, ha ha.
Since it can be defined as an automatic call, we are not the above HasCreator
change about it:
namespace App\Traits;
trait HasCreator { public static function hasCreator() // -> 改为 bootHasCreator { static::saving(function ($model) { $model->creator_id = $model->creator_id ?? 1; }); } }
It has been invoked automatically, then:
namespace App;
use App\Traits\HasCreator; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Post extends Model { use HasCreator, SoftDeletes; protected $fillable = ['title', 'user_id']; }
So can you!
That method before and behind hasCreator
is the same, as their method calls Jiuhaola, whether declared as static to see their own needs.
Here we recommend some of the projects with the resulting Trait
, are plucked from the ultra-brother there, ha ha.
Small Case
HasCreator
Specifies the creator
namespace App\Traits;
use App\User; /** * Trait HasCreator. * * @property \App\User $creator */ trait HasCreator { public static function bootHasCreator() { static::saving(function ($model) { $model->creator_id = $model->creator_id ?? \auth()->id(); }); } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function creator() { return $this->belongsTo(User::class, 'creator_id')->withTrashed(); } /** * @param \App\User|int $user * * @return bool */ public function isCreatedBy($user) { if ($user instanceof User) { $user = $user->id; } return $this->creator_id == \intval($user); } }
Trait
Defines three methods, now give you a brief explanation of Kazakhstan:
- bootHasCreator: Default given the current authenticated user. As the following
static::saving
do not understand, before you can see the article clatter. - creator: correlation model definition
- isCreatedBy: to determine whether the user is the creator of the incoming current
BelongsToUser
Specifies the user
namespace App\Traits;
use App\User; /** * Trait BelongsToUser. * * @property \App\User $user */ trait BelongsToUser { public static function bootBelongsToUser() { static::creating(function ($model) { if (!$model->user_id) { $model->user_id = \auth()->id(); } }); } /** * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function user() { return $this->belongsTo(User::class)->withTrashed(); } /** * @param \App\User|int $user * * @return bool */ public function isOwnedBy($user) { if ($user instanceof User) { $user = $user->id; } return $this->user_id == \intval($user); } }
I will not explain it, and above is about the same, we see to understand.
Conclusion
It is simple to tell you about Trait
in Laravel
, write wrong place and how to use the supplement are welcome to leave a message Oh, ha ha.
Related links: "I understand PHP Trait" (deeper explanation of Trait - produced super brother, ha ha), "to grasp the concept and usage of PHP Trait"