Trait とは
- PHP 5.4.0 以降で導入されたコードを再利用するための仕組みのことです。
- いくつかのメソッド群を異なるクラス階層にある独立したクラスで再利用できるようにします。
Class との違い
- Trait の目的はあくまでも機能をまとめるためだけに限定されます。
- インスタンスを生成することはできません。
使うことのメリット
- 多重継承や Mixin に関連するありがちな問題を回避することができます。
- 振る舞いを水平方向で構成できるようになります。
優先順位
現在の基底クラスのメソッド → トレイトのメソッド → 継承したクラスのメソッド
実際に使ってみる。
簡単な例は公式に書いてあるので、ここではありそうな例として値を保存しようとした時のカスタムリクエストにバリデーションをかける時の処理をまとめてみます。
フレームワークは laravel5.5 を使っています。
before
use Illuminate\Validation\Validator;
class CustomRequest extends BaseRequest
{
/**
* @param Validator $validator
*/
public function withValidator(Validator $validator)
{
$validator->after(function (Validator $validator) {
$inputs = $this->validatedValues();
// このバリデーションをTraitで再利用できるようにしましょう ---------
if ($inputs['sample']['hoge']) {
$validator->errors()->add('hoge', 'error message.');
}
// ---------------------------------------------------------
return $validator->messages()->isEmpty();
});
}
}
use Illuminate\Database\Eloquent\Model;
/**
* Class Sample
* Sampleテーブルを操作するModelクラスです。
*/
class Sample extends Model
{
// Eloquent save etc...
}
after
CustomRequestと同じ階層に Trait を作ってみます。
use Illuminate\Validation\Validator;
/**
* Trait CustomValidationRule
*/
trait CustomValidationRule
{
/**
* @param Validator $validator
* @param Sample $sample
*/
protected function checkHoge(Validator $validator, Sample $sample)
{
if ($sample['hoge']) {
$validator->errors()->add('hoge', 'error message.');
}
}
}
use Illuminate\Validation\Validator;
class CustomRequest extends BaseRequest
{
// 使用したいクラス内で Trait を宣言します
use CustomValidationRule;
/**
* @param Validator $validator
*/
public function withValidator(Validator $validator)
{
$validator->after(function (Validator $validator) {
$inputs = $this->validatedValues();
// Trait で宣言した関数を呼ぶ ---------------------------------
$this->checkHoge($validator, (new Sample($inputs['sample'])));
// ---------------------------------------------------------
return $validator->messages()->isEmpty();
});
}
}
衝突の解決
- 同じ名前のメンバーを含む複数のトレイトを追加するときには、 衝突を明示的に解決しておかないと fatal エラーが発生するので注意が必要。
【参考: https://www.php.net/manual/ja/language.oop5.traits.php 】