上級へ続く “中間地点” 「あるはず」を疑う

例えば配列の整数キー 5にデータがあるときは、以下のようなコードで値を取り出すと思います。
$value = $arr[5];
同様に、連想配列で name のキーの値であれば、以下になるかと思います。
$name = $harr["name"];

想定範囲内でコードが動いている場合は上述でも問題ないと思うのですが。
では、もし「指定したキーがなかった」場合、どうなるでしょうか?

PHPの基本的な挙動としては「Warning(PHP 8.0より前はNotice)が発生した」上で、値はnullになります。
では、この挙動は「期待している、あるいは望ましい」ものでしょうか?

仕事としてコードを書き、また上級になっていくほどに「WarningやNoticeは、出力を抑止するのではなく、そもそも出ないようなコードにしていく」といった方向に技術を磨いていくことは多くなるかと思います。
なぜなら、それを無視すると「思わぬバグに遭遇する」ことがあり得るからです。

そのために、配列に「そのキーがあるかどうか」を確認する、ということが、よく行われます。
またその時に合わせて「指定したキーがない場合の挙動」を、想定します。

一つよくあるのは「なかったら、代替の、またはデフォルトの値を使う」という書き方です。
古くから、PHPではarray_key_exists()isset()を使って、キーや値の状態を確認してきました。1行にするために三項演算子を併用することも多かったと思います。
(array_key_exists()isset() では挙動にわずかに違いがあるので、調べてみるとよいでしょう。ヒントは「値がnullの時」の挙動に、差異があります)
ただ、最近では「キーが存在しない場合、または値が null の場合」に、代替の、またはデフォルトの値を使う時、null合体演算子もよく使われます。
null合体演算子は、例えばこんな風に記述します。
$name = $harr["name"] ?? "名無し";

とはいえこれで、もしキーにtypoがあって
$name = $harr["nmae"] ?? "名無し";
としてしまうと、本来のキー name を参照していないため、期待した値を取得できないというバグにつながります。
このあたりへの対策はUnitTestなどの「別の方法」でのアプローチが必要になります、というあたりも「上級に進む道程」の1つですね。

もう一つが「なかったら、異常として扱い、例外を投げる」やり方です。
こちらについてはarray_key_exists()isset()を使う方法が多かったのですが、PHP8で「throw キーワードが式として扱えるようになった」ために、以下のような書き方ができるようになりました。
$name = $harr["name"] ?? throw new \Exception("nameがありません");

コードを書く時に、まずはじめはまっすぐに「やりたいこと」を見据えて書いていくと思います。俗に言う「正常系」です。
それはとても素晴らしいことです。
しかし、特に業務などでコードを書く場合、同じくらいに「そのやりたいことの途中に、想定外のことが起きたら?」を考え始めます。「異常系」の対応ですね。
この「異常系」に対する考察と、それを実装する技術力がとても重要になってきます。

是非、「やりたいことがなんとなく書けるようになった」ら、次は「その途中にある、想定外の事象」を考え、対応できるようになってみるとよいでしょう。

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次