Code Fix

上級

__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                ;
                              ^
Fatal error: Uncaught Error: Object of class Money could not be converted to string in main.php:6

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                  ;
                             ^
Fatal error: Uncaught Error: Object of class Temperature could not be converted to string in main.php:6

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                 ;
                               ^
Fatal error: Uncaught Error: Object of class Distance could not be converted to string in main.php:6

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                ;
                               ^
Fatal error: Uncaught Error: Object of class Weight could not be converted to string in main.php:6

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              ;
                             ^
Fatal error: Uncaught Error: Object of class Speed could not be converted to string in main.php:6

Speedに__toString()が無いため、オブジェクトを直接文字列と連結できません。

直し方: $s を $s->kmh にします。

この問題を解いてみる →

よくある誤解

「オブジェクトも文字列と連結すれば、なんとなく変換されて表示されるはず」という思い込みは誤りです。PHPはオブジェクトから文字列への変換方法を自動では決められないため、__toString()の実装がなければ致命的エラーになります。

実務での勘所

__toString()が必要になるのは、オブジェクトを実際に「文字列」として扱う場面(echo、文字列連結の.、文字列への明示的なキャストなど)に限られます。var_dump()やprint_r()は、オブジェクトを文字列に変換しているわけではなく、独自の方法でオブジェクトの中身を人間向けに整形して表示しているため、__toString()が無くてもエラーになりません。デバッグ中にvar_dumpでは正常に見えていたオブジェクトが、echoや.で使った途端にエラーになるのは、この2種類の「表示」がまったく別の仕組みで動いているためです。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)