PHP Notice: Undefined variable: 変数名 in /***/***.php on line 2
PHPで変数や対象のキーが存在しない配列を使おうとすれば、上記のようなエラーが吐き出されますね。PHP5.6までは初期値を設定したり、issetで判定したりしてそれを回避していましたが、2015年末にリリースされたPHP7からは新しくNull合体演算子が追加されて簡単に判定ができるようになりました。
今回は、Null合体演算子がどういった動きをするのかをサンプルコードを用いてご紹介します。
PHPマニュアル「Null合体演算子」
Null合体演算子
PHP7からNull合体演算子(クエスチョンマーク2つ)が追加されました。これを使うと存在チェックがスマートに書けるため、PHP7以上の環境が推奨されている現在ではぜひ覚えておきたい記述方法の1つです。
[存在チェックの対象かつ存在した場合] ?? [存在しなかった場合]
まずは存在チェックの方法をif文と三項演算子とNull合体演算子の3パターンを見てみましょう。$a〜cはどれも存在していませんので、同じ結果が返ってきます。
<?php
// もし$aが存在していれば$aをセット
/*
* PHP5.6以前
*/
// if文
if(isset($a)){
$result = $a;
}else{
$result = '存在せんぞ';
}
echo $result; # 存在せんぞ
// 三項演算子
isset($b) ? $result = $b : $result = '存在せんぞ';
echo $result; # 存在せんぞ
/*
* PHP7以降
*/
// Null合体演算子
$result = $c ?? '存在せんぞ';
echo $result; # 存在せんぞ
?>
変数
では、変数のチェックでNull合体演算子を使った際の動きを見てみましょう。
<?php
$a = $a ?? '存在せんぞ';
echo $a; # 存在せんぞ
$b = null;
$b =$b ?? 'nullちゃうか?';
echo $b; # nullちゃうか?
$c = 0;
$c = $c ?? '存在せんぞ';
echo $c; # 0
?>
$aはNull合体演算子を使った時点では宣言されていませんね。そのため、存在がないと判定されて??の後ろに記述した「存在せんぞ」が$aにセットされ、echoすれは「存在せんぞ」と出力されます。
$bにはnullをセットしてしています。変数自体は存在していますが、issetと同様にnullはfalseで判定されるため、$bには「nullちゃうか?」がセットされ、echoすれば「nullちゃうか?」と出力されます。
$cには数字の0をセットしています。こちらは存在していると判定されるため、$cにはそのまま0がセットされ、echoすれば0が出力されます。
Null合体演算子の判定はissetと同じなので、判定は以下の表を参考にしてください。
値 |
判定結果 |
---|---|
[存在しない] |
false |
null |
false |
“” |
true |
0 |
true |
“0” |
true |
array() |
true |
配列
次は配列に対するNull合算演算子の動きです。実際にどういった判定がされるのかを見てみましょう。
<?php
$a = []; # array()
$a = $a ?? '空っぽや';
var_dump($a); # array(0){}
?>
判定基準はissetと同じため、空配列を存在チェックにかければtrueと判定されるため、var_dumpすれば$aは空配列を出力します。
では次に、配列の中身をチェックしてみましょう。
<?php
$a = ['ゼロ番目'];
$a = $a[0] ?? 'なかったで';
echo $a; # ゼロ番目
$b = ['apple'=>null];
$b = $b['apple'] ?? 'なかったで';
echo $b; # なかったで
$c = ['apple'=>'りんご'];
$c = $c['orange'] ?? 'みかん買い忘れたわ・・・';
echo $c; # みかん買い忘れたわ・・・
?>
最初は$a[0]で配列にキー指定されていない要素が入っているかの確認です。こちらは存在しているので、判定の結果は配列にいれた「ゼロ番目」という文字が出力されました。
次にappleというキーでnullを入れた$bの連想配列ですが、$b[‘apple’]の結果はnullなのでfalseが返され、出力の結果は「なかったで」になります。
最後はappleのキーにりんごと入れた$cの連想配列で、orangeのキーを持った要素があるかをチェックしています。ですが、$cの連想配列内にはorangeは存在しないのでfalseが返され、出力の結果は「みかん買い忘れたわ・・・」になります。
配列内に該当のキーが存在しているかどうかを確認するケースは多いので、お問い合わせフォームなど配列の受け渡しをする場面ではNull合体演算子を使うと記述量を少なくすることができます。
<form action="/" method="post">
<input type="text" name="name" value="<?= $_POST['name'] ?? '' ?>">
<input type="submit" value="送信">
</form>
必須項目でない項目を確認画面へ飛ばして表示する場合、存在チェックがなければエラーを吐き出してしまうので、存在確認をしなければなりません。今までであればissetを使って実装していましたが、Null合体演算子を使えば、このように簡潔に書けるため、コードの視認性も良くなりますね。
条件分岐での活用
Null合体演算子では変数を代入するだけではなく、条件分岐で活用することもできます。
switchを使って動きを見てみましょう。
<?php
$b = 'b';
switch ($a ?? $b) {
case 'a':
echo 'aやで';
break;
case 'b':
echo 'bやで';
break;
default:
echo '該当せんで';
break;
}
// 結果:bやで
?>
switchでチェックする対象にNull合体演算子を使っていますね。もし$aが存在すれば$aの値を、なければ$bの値を使ってswitchをしてくれています。
上記のコード内で$aは定義されていないので、switchの判定には$bが使われてcase ‘b’の「bやで」が出力されました。
では次に、$aを定義してみましょう。
<?php
$a = 'a';
$b = 'b';
switch ($a ?? $b) {
case 'a':
echo 'aやで';
break;
case 'b':
echo 'bやで';
break;
default:
echo '該当せんで';
break;
}
// 結果:aやで
?>
今回は$aが存在しているので、switchの判定には$aが使われましたね。このように、条件式にNull合体演算子を入れることもできるので、状況によって対象を変更したいといった場合には活用することができます。
三項演算子やNull合体演算子を使うと、入れ子にして数行にもなるコードを1行にまとめることができますが、その判定数が多すぎると逆に視認性が悪くなってしまいます。なので、この方法が使えるからと言って無理やり採用するのではなく、あくまで一目見てどういった処理がされているのかわかりやすいような書き方をするようにしましょう。
まとめ
いかがだったでしょうか。
今回はPHP7から追加されたNull合体演算子について紹介しました。
これからの開発やサイト制作(PHP7以上の環境)で存在チェックをする際にはこの方法を使えばスマートな記述ができるようになるので、ぜひ参考にしてくださいね。