Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

PHP辞典

  1. トップページ
  2. PHP辞典
  3. trait / マジックメソッド

trait / マジックメソッド対応: PHP 5.4(2012)

トレイトで再利用可能なメソッドを定義し、マジックメソッドでオブジェクトの特殊な振る舞いを制御する仕組みです。

構文
// トレイトを定義します。
trait トレイト名 {
	public function method() { }
}

// トレイトをクラスに組み込みます。
class クラス名 {
	use トレイト名;
}

// instanceof でオブジェクトの型を判定します。
$obj instanceof クラス名;
構文一覧
構文概要
trait再利用可能なメソッド群を定義します。クラスに『use』で組み込むことで、単一継承の制約を超えてメソッドを共有できます。
useクラス内でトレイトを組み込むキーワードです。カンマ区切りで複数のトレイトを同時に使用できます。
instanceofオブジェクトが指定したクラスやインターフェースのインスタンスかどうかを判定します。『true』または『false』を返します。
主なマジックメソッド
メソッド概要
__toString()オブジェクトが文字列として扱われた際に自動的に呼び出されます。『echo $obj;』のように使えます。
__get($name)存在しないプロパティやアクセス不可のプロパティを読み取ろうとした際に呼び出されます。
__set($name, $value)存在しないプロパティやアクセス不可のプロパティに値を代入しようとした際に呼び出されます。
__call($name, $args)存在しないメソッドやアクセス不可のメソッドを呼び出した際に呼び出されます。
__invoke(...$args)オブジェクトを関数のように呼び出した際に呼び出されます。『$obj()』の形で使えます。
__clone()『clone』でオブジェクトを複製した際に呼び出されます。ディープコピーが必要な場合に使用します。
サンプルコード
<?php
// トレイトの基本的な使い方です。
trait Timestampable {
	private string $created_at;
	private string $updated_at;

	public function set_timestamps(): void {
		$now = date('Y-m-d H:i:s');
		$this->created_at = $this->created_at ?? $now;
		$this->updated_at = $now;
	}

	public function get_created_at(): string {
		return $this->created_at;
	}
}

trait SoftDeletable {
	private ?string $deleted_at = null;

	public function soft_delete(): void {
		$this->deleted_at = date('Y-m-d H:i:s');
	}

	public function is_deleted(): bool {
		return $this->deleted_at !== null;
	}
}

// 複数のトレイトを組み合わせて使用します。
class Post {
	use Timestampable, SoftDeletable;

	public function __construct(
		public string $title
	) {
		$this->set_timestamps();
	}
}

$post = new Post("PHPトレイト入門");
echo $post->get_created_at(); // 現在日時が出力されます。
$post->soft_delete();
var_dump($post->is_deleted()); // 『bool(true)』と出力されます。

// __toString() マジックメソッドの例です。
class Money {
	public function __construct(
		private int $amount,
		private string $currency = '円'
	) {}

	public function __toString(): string {
		return number_format($this->amount) . $this->currency;
	}
}

$price = new Money(2980);
echo $price; // 『2,980円』と出力されます。__toString() が自動的に呼ばれます。

// __get() と __set() の例です。
class FlexibleObject {
	private array $data = [];

	public function __get(string $name): mixed {
		return $this->data[$name] ?? null;
	}

	public function __set(string $name, mixed $value): void {
		$this->data[$name] = $value;
	}
}

$obj = new FlexibleObject();
$obj->color = "赤"; // __set() が呼ばれます。
echo $obj->color;   // __get() が呼ばれ、『赤』と出力されます。

// __invoke() の例です。
class Multiplier {
	public function __construct(
		private int $factor
	) {}

	public function __invoke(int $value): int {
		return $value * $this->factor;
	}
}

$double = new Multiplier(2);
echo $double(5);  // 『10』と出力されます。オブジェクトを関数のように呼び出せます。
echo $double(15); // 『30』と出力されます。

// instanceof で型を判定します。
var_dump($post instanceof Post);          // 『bool(true)』と出力されます。
var_dump($price instanceof Money);        // 『bool(true)』と出力されます。
var_dump($price instanceof \Stringable);  // 『bool(true)』と出力されます。__toString() を持つためです。
概要

トレイトはPHP 5.4 で導入された、コードの再利用を実現する仕組みです。PHPは単一継承のため複数のクラスから機能を継承できませんが、トレイトを使えば複数の機能をクラスに自由に組み込めます。タイムスタンプの管理、ソフトデリート、ログ出力など、複数のクラスで共通する振る舞いを定義するのに適しています。

マジックメソッドはPHPが特定の状況で自動的に呼び出す特殊なメソッドです。『__toString()』はオブジェクトの文字列表現を定義し、『__get()』『__set()』は動的なプロパティアクセスを制御します。『__invoke()』を定義するとオブジェクトを関数のように呼び出せるため、コールバックとして渡す場面で便利です。

クラスの基本については『class』、継承とインターフェースについては『extends / implements』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。