Code Fix

上級

nullになりうるプロパティへのメソッド呼び出しは ?-> で守る

途中のプロパティがnullかもしれないオブジェクトの連鎖に対して、通常の->でメソッドを呼ぶと致命的エラーになります。?->を使うと、途中がnullの場合は例外を投げずnullを返して処理を続けられます。

エラーメッセージの読み方

Fatal error: Uncaught Error: Call to a member function getCity() on null in main.php:9
main.php
ファイル名
9
行番号 — 実際にクラッシュした行
Error
例外クラス — 何が起きたか。ここを検索するのが最短です
Call to a member function getCity() on null
内容 — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  <?php
 2  class User {
 3      public ?Address $address = null;
 4  }
 5  class Address {
 6      public function getCity(): string { return "Tokyo"; }
 7  }
 8  $u = new User();
 9  echo $u->address-> getCity();
                     ^
Fatal error: Uncaught Error: Call to a member function getCity() on null in main.php:9

$u->addressはnullのままです。通常の->でメソッドを呼ぶと致命的エラーになります。?->を使えば、途中がnullの場合は例外を投げずnullを返して処理を続けられます。

直し方: -> を ?-> にします。

この問題を解いてみる →

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

パターン2

 1  <?php
 2  class Order {
 3      public ?Customer $customer = null;
 4  }
 5  class Customer {
 6      public function getName(): string { return "Al"; }
 7  }
 8  $o = new Order();
 9  echo $o->customer-> getName();
                      ^
Fatal error: Uncaught Error: Call to a member function getName() on null in main.php:9

$o->customerがnullのまま->でメソッドを呼ぶと致命的エラーです。?->を使うとnullの場合は安全にnullを返します。

直し方: -> を ?-> にします。

この問題を解いてみる →

パターン3

 1  <?php
 2  class Post {
 3      public ?Author $author = null;
 4  }
 5  class Author {
 6      public function getEmail(): string { return "a@example.com"; }
 7  }
 8  $p = new Post();
 9  echo $p->author-> getEmail();
                    ^
Fatal error: Uncaught Error: Call to a member function getEmail() on null in main.php:9

$p->authorはnullなので、通常の->での呼び出しは致命的エラーになります。?->に変えることで安全に処理を続けられます。

直し方: -> を ?-> にします。

この問題を解いてみる →

パターン4

 1  <?php
 2  class Team {
 3      public ?Coach $coach = null;
 4  }
 5  class Coach {
 6      public function getName(): string { return "Ken"; }
 7  }
 8  $t = new Team();
 9  echo $t->coach-> getName();
                   ^
Fatal error: Uncaught Error: Call to a member function getName() on null in main.php:9

$t->coachはnullのままです。通常の->でメソッドを呼ぶと致命的エラーになります。

直し方: -> を ?-> にします。

この問題を解いてみる →

パターン5

 1  <?php
 2  class Cart {
 3      public ?Discount $discount = null;
 4  }
 5  class Discount {
 6      public function getRate(): string { return "10%"; }
 7  }
 8  $c = new Cart();
 9  echo $c->discount-> getRate();
                      ^
Fatal error: Uncaught Error: Call to a member function getRate() on null in main.php:9

$c->discountがnullのまま->でメソッドを呼ぶと致命的エラーです。

直し方: -> を ?-> にします。

この問題を解いてみる →

よくある誤解

「nullチェックはif文で毎回書くしかない」という思い込みは、?->を知らないと起きがちです。ネストが深いほど毎回のnullチェックは冗長になり、?->を使えば1箇所で安全に済みます。

実務での勘所

?->はJavaScriptのオプショナルチェイニング(?.)と同様、途中が1箇所nullになった時点で、その先に連なる呼び出し全体を評価せずに打ち切ります。$a?->getB()?->getC()のようにチェーンしている場合、$aがnullであれば、getB()やgetC()の呼び出し自体が実行されず、式全体がnullになります。「?->を書いた箇所だけが安全になる」のではなく「そこから右側の連鎖全体が短絡評価される」という理解が正確です。

演習をはじめる

関連するエラー

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