マジックメソッド入門
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 44/91。
マジックメソッドは、2つのアンダースコア(__)で始まるPHPの特殊なメソッドであり、特定のイベントやアクションに応じてPHPによって自動的に呼び出されます。すでにそのうちの2つ、__construct() と __destruct() を使用しました。
これらのメソッドを使用すると、PHPの内部動作にフックし、オブジェクトが一般的な操作に対してどのように応答するかをカスタマイズできます。
例えば、オブジェクトをプリントしようとすると何が起こるでしょうか?あるいは、存在しないプロパティにアクセスしようとするとどうなるでしょうか?マジックメソッドを使用すると、これらの状況を制御できるようになります。
最もよく使われるマジックメソッドの簡単な概要は以下の通りです。
| メソッド | 実行タイミング |
|---|---|
__construct() | オブジェクトが生成されたとき |
__destruct() | オブジェクトが破棄されたとき |
__toString() | オブジェクトが文字列として扱われたとき |
__get() | 未定義のプロパティにアクセスしたとき |
__set() | 未定義のプロパティに値を代入したとき |
__call() | 未定義のメソッドを呼び出したとき |
__clone() | オブジェクトが複製されたとき |
<?php
class Book {
public function __construct(
private string $title
) {}
public function __toString(): string {
return "Book: " . $this->title;
}
}
$book = new Book("PHP Mastery");
echo $book;
出力:
Book: PHP Mastery__toString() がなければ、オブジェクトを echo しようとするとエラーが発生します。このマジックメソッドはこのアクションをインターセプトし、代わりに文字列形式を返します。今後のレッスンでは、各マジックメソッドについて詳しく説明します。
チャレンジ
簡単マジックメソッドを紹介する映画カタログシステムを構築しましょう。Movieクラスを作成し、__construct()を使用して映画データを初期化し、__toString()を使用してオブジェクトがプリントされたときにクリーンな文字列表現を提供します。
コードは2つのファイルに分けて構成します:
Movie.php— カタログ内の映画を表すMovieクラスを作成します。コンストラクタのプロパティ昇格(constructor promotion)を使用して、$title(string)、$director(string)、$year(integer)のプライベートプロパティを定義します。__toString()マジックメソッドを実装して、"[title] ([year]) - Directed by [director]"という形式の文字列を返すようにします。これにより、別のメソッドを呼び出すことなく、映画オブジェクトを直接echoできるようになります。main.php— Movieファイルをインクルードします。映画のタイトル、監督名、公開年の3つの入力を受け取ります。これらの値を使用してMovieインスタンスを作成します(年は整数に変換してください)。その後、映画オブジェクトを直接echoするだけです。__toString()メソッドが自動的に呼び出され、出力が生成されます。
__toString()の魔法は、オブジェクトが文字列のコンテキストで使用されるたびに、PHPが自動的にそれを呼び出すことです。echo $movie->getInfo();と書く代わりに、単にecho $movie;と書くだけで、PHPが変換を処理してくれます。これにより、オブジェクトをより直感的に扱うことができるようになります。
チートシート
マジックメソッドは、PHPにおける特殊なメソッドで、2つのアンダースコア(__)で始まり、特定のイベントやアクションに応じてPHPによって自動的に呼び出されます。
一般的なマジックメソッド:
| メソッド | 実行されるタイミング |
|---|---|
__construct() | オブジェクトが作成されたとき |
__destruct() | オブジェクトが破棄されたとき |
__toString() | オブジェクトが文字列として使用されたとき |
__get() | 未定義のプロパティにアクセスしたとき |
__set() | 未定義のプロパティに値を代入したとき |
__call() | 未定義のメソッドを呼び出したとき |
__clone() | オブジェクトが複製されたとき |
__toString() メソッドは、オブジェクトの文字列表現を返します:
<?php
class Book {
public function __construct(
private string $title
) {}
public function __toString(): string {
return "Book: " . $this->title;
}
}
$book = new Book("PHP Mastery");
echo $book; // 出力: Book: PHP Mastery
__toString() がないと、オブジェクトを echo しようとするとエラーが発生します。マジックメソッドはこのアクションをインターセプトし、オブジェクトを文字列のコンテキストで使用できるようにします。
自分で試してみよう
<?php
require_once 'Movie.php';
// 入力を読み込む
$title = trim(fgets(STDIN));
$director = trim(fgets(STDIN));
$year = intval(fgets(STDIN));
// TODO: 入力値を使用してMovieインスタンスを作成する
// TODO: movieオブジェクトを直接echoする(__toString()メソッドが自動的に呼び出されます)
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。