LoginSignup
1
2

More than 3 years have passed since last update.

PHP の Trait ってなんだ

Last updated at Posted at 2019-09-18

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2