__toString未実装のオブジェクトを文字列化した原因
__toString()メソッドを持たないオブジェクトを文字列と連結したり、文字列として出力しようとしたりすると致命的エラーになります。オブジェクトを文字列として扱いたい場合は__toString()を実装する必要があります。
エラーメッセージの読み方
Fatal error: Uncaught Error: Object of class Money could not be converted to string in main.php:6
main.php- ファイル名
6- 行番号 — 実際にクラッシュした行
Error- 例外クラス — 何が起きたか。ここを検索するのが最短です
Object of class Money could not be converted to string- 内容 — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 <?php 2 class Money { 3 public function __construct(public int $cents) {} 4 } 5 $m = new Money(500); 6 echo "Price: " . $m ; ^
Moneyクラスは__toString()を持たないため、オブジェクトそのものを文字列と連結できません。プロパティの値($m->cents)のように文字列化できる値を渡す必要があります。
直し方: $m を $m->cents にします。
パターン2
1 <?php 2 class Temperature { 3 public function __construct(public float $celsius) {} 4 } 5 $t = new Temperature(25.5); 6 echo "Now: " . $t ; ^
Temperatureに__toString()が無いため、オブジェクトを直接文字列と連結できません。$t->celsiusのように具体的な値を使う必要があります。
直し方: $t を $t->celsius にします。
パターン3
1 <?php 2 class Distance { 3 public function __construct(public int $meters) {} 4 } 5 $d = new Distance(150); 6 echo "Length: " . $d ; ^
Distanceは__toString()を実装していないため、オブジェクト自体を文字列連結に使うと致命的エラーになります。$d->metersのような値を使います。
直し方: $d を $d->meters にします。
パターン4
1 <?php 2 class Weight { 3 public function __construct(public int $grams) {} 4 } 5 $w = new Weight(300); 6 echo "Weight: " . $w ; ^
Weightクラスは__toString()を持たないため、オブジェクトそのものを文字列と連結できません。
直し方: $w を $w->grams にします。
パターン5
1 <?php 2 class Speed { 3 public function __construct(public int $kmh) {} 4 } 5 $s = new Speed(80); 6 echo "Speed: " . $s ; ^
Speedに__toString()が無いため、オブジェクトを直接文字列と連結できません。
直し方: $s を $s->kmh にします。
よくある誤解
「オブジェクトも文字列と連結すれば、なんとなく変換されて表示されるはず」という思い込みは誤りです。PHPはオブジェクトから文字列への変換方法を自動では決められないため、__toString()の実装がなければ致命的エラーになります。
実務での勘所
__toString()が必要になるのは、オブジェクトを実際に「文字列」として扱う場面(echo、文字列連結の.、文字列への明示的なキャストなど)に限られます。var_dump()やprint_r()は、オブジェクトを文字列に変換しているわけではなく、独自の方法でオブジェクトの中身を人間向けに整形して表示しているため、__toString()が無くてもエラーになりません。デバッグ中にvar_dumpでは正常に見えていたオブジェクトが、echoや.で使った途端にエラーになるのは、この2種類の「表示」がまったく別の仕組みで動いているためです。