- カテゴリ: 変数・配列の存在チェック(PHP標準構文)
- 対象バージョン: PHP 7.4 〜 8.4(言語構文として長期的に安定。null合体演算子
??はPHP 7.0以降) - 主な関数/構文:
isset()/empty()/is_null()/array_key_exists()/??(null合体演算子) - 関連: empty関数 / 連想配列の基礎 / Laravelでのisset・null判定
- 変更履歴: 言語構文自体の仕様は長期的に安定。PHP 7.0でnull合体演算子
??、PHP 7.4で型付きプロパティが追加され、isset()との組み合わせ方の選択肢が増えた
要点(TL;DR)
isset($var)は「変数が定義済みで、かつnullではない」ときにtrueを返す言語構文。未定義変数に使ってもエラーにならず安全に判定できる- 配列のキー確認は
isset($arr['key'])、ネストした配列・オブジェクトのプロパティもisset($arr['a']['b'])のようにチェーンして一度に確認できる - 複数の変数をまとめてチェックするなら
isset($a, $b, $c)。すべてが定義済みかつnullでない場合のみtrue - 値が
nullかどうかしか見ないので、0や""、falseは「セットされている」扱いになる。「空かどうか」を見たい場合はempty()を使う - デフォルト値を当てたいだけなら、
isset()のif文より??(null合体演算子)や??=のほうが1行で書けて読みやすい
概要
issetはPHPの言語構文(関数ではなく特殊な構文)で、指定した変数・配列要素・オブジェクトのプロパティが「定義されていて、かつnullではない」かどうかを確認します。$_POSTや$_GETのような未定義かもしれない配列キーへ直接アクセスするとPHPは警告(Undefined array key)を出しますが、isset()で先にチェックしてからアクセスすればこの警告を避けられます。この記事では基本構文から配列・オブジェクトでの使い方、empty()や??との使い分け、よくある間違いまでを実際に動かせるコード例とともに解説します。
構文 / シグネチャ
bool isset(mixed $var, mixed ...$vars)
第一引数だけでなく可変長引数を受け取れるため、isset($a, $b, $c)のように複数の変数を一度に渡せます。この場合、渡したすべての変数が定義済みかつnullでないときだけtrueを返します(1つでも条件を満たさなければ、その時点で残りの評価を打ち切る短絡評価)。関数ではなく言語構文なので、変数・配列要素・プロパティ以外の「式」(関数の戻り値など)を直接渡すことはできません。
isset・empty・is_null・array_key_existsの違い
| 関数/構文 | trueになる条件 | 未定義変数に使った場合 | 主な用途 |
|---|---|---|---|
isset($var) | 定義済み かつ nullではない | エラーにならずfalse | 変数・配列キーが「使える状態」かの確認 |
empty($var) | 未定義、またはnull/0/""/"0"/false/空配列 | エラーにならずtrue | 「実質的に空」かどうかの確認 |
is_null($var) | 値がnullと厳密に一致 | PHP Warning: Undefined variableが発生 | 変数が定義済みである前提でnullかを確認 |
array_key_exists('key', $arr) | 配列にキーが存在する(値がnullでもtrue) | -(配列自体は必要) | 値がnullでもキーの有無だけを見たいとき |
最も混同しやすいのがisset()とarray_key_exists()の違いです。配列のキーにnullを代入した場合、isset($arr['key'])はfalseを返しますが、array_key_exists('key', $arr)はtrueを返します。「キー自体があるかどうか」を厳密に確認したい場合はarray_key_exists()を使ってください。
<?php
$data = ['name' => null];
var_dump(isset($data['name'])); // bool(false)
var_dump(array_key_exists('name', $data)); // bool(true)
使用例
基本的な使い方
<?php
$name = "John Doe";
if (isset($name)) {
echo "変数nameはセットされています。";
} else {
echo "変数nameはセットされていません。";
}
// 出力: 変数nameはセットされています。
$age = null;
var_dump(isset($age)); // bool(false) nullなのでfalse
var_dump(isset($undefinedVar)); // bool(false) 未定義変数でもエラーにならない
未定義の変数をisset()に渡してもエラーや警告は発生しません。これはisset()が「変数へのアクセスを試みる前に」定義状況を確認する特殊な構文だからです。
複数変数をまとめてチェックする
<?php
$firstName = "John";
$lastName = "Doe";
$middleName = null;
var_dump(isset($firstName, $lastName)); // bool(true)
var_dump(isset($firstName, $lastName, $middleName)); // bool(false) middleNameがnullのため
配列のキー・ネストした要素をチェックする
<?php
$user = [
'name' => 'Taro',
'profile' => [
'email' => 'taro@example.com',
],
];
var_dump(isset($user['name'])); // bool(true)
var_dump(isset($user['profile']['email'])); // bool(true) ネストしたキーもチェーンで確認できる
var_dump(isset($user['profile']['phone'])); // bool(false) 存在しないキー
var_dump(isset($user['address']['zip'])); // bool(false) 途中のキーが無くてもエラーにならない
isset()はチェーンの途中のキーが存在しなくても警告を出さずにfalseを返します。深いネストの存在確認を安全に行える点がisset()の大きな利点です。オブジェクトのプロパティも同様にisset($obj->prop->child)のように確認できます。
Webフォームの入力チェック($_POST)
<?php
if (isset($_POST['username'], $_POST['email'])) {
$username = $_POST['username'];
$email = $_POST['email'];
// バリデーション・保存処理などを続ける
} else {
echo "必須項目が入力されていません。";
}
$_POSTや$_GETのキーは送信されなければ存在しません。直接アクセスするとUndefined array keyの警告が出るため、isset()で先に存在確認してからアクセスするのが定石です。
デフォルト値を当てるならnull合体演算子(??)
<?php
// isset()を使ったif文での書き方
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = 1;
}
// null合体演算子(??)を使うと1行で書ける
$page = $_GET['page'] ?? 1;
// 変数自体に代入したいときは null合体代入演算子(??=)
$config['timeout'] ??= 30;
$a ?? $bは「$aがisset($a)でtrueならその値、falseなら$b」を返す構文で、内部的にはisset()と同じ判定基準(未定義またはnullならフォールバック)を使っています。単純に「値が無ければデフォルト値を使う」だけの用途であれば、isset()のif文より??のほうが簡潔です。
APIレスポンス(連想配列)の検証
<?php
$response = json_decode($apiResponseJson, true);
if (isset($response['data']['id'], $response['data']['name'])) {
$id = $response['data']['id'];
$name = $response['data']['name'];
} else {
throw new RuntimeException('Invalid API response: required fields are missing.');
}
外部APIのレスポンス構造は必ずしも保証されないため、想定しているキーが揃っているかをisset()でまとめて確認してから後続処理に進むと、未定義キーへのアクセスによる警告やnullエラーを防げます。
よくある落とし穴・注意
- 値が
0や空文字でもisset()はtrue:isset()が見ているのは「nullかどうか」だけです。フォーム入力で「値が空欄かどうか」を判定したい場合はisset()ではなくempty()やtrim($val) === ''を使う必要があります。 - 関数の戻り値には直接使えない:
isset()は言語構文のため、isset(getUser())のように関数呼び出しの結果を直接渡すことはできません(構文エラー)。関数の戻り値をチェックしたい場合は、一度変数に代入してからisset($result)とするか、$result !== nullを使います。 - キーに
nullを代入すると「存在しない」扱いになる:$arr['key'] = null;のように明示的にnullを代入すると、array_key_exists()はtrueを返す一方でisset()はfalseになります。「キーの有無」を知りたいのか「使える値があるか」を知りたいのかを区別しましょう。 - 型付きプロパティ(PHP 7.4以降)が未初期化だと直接アクセスはエラーになる:クラスの型付きプロパティにデフォルト値を与えず未初期化のままアクセスすると
Error: must not be accessed before initializationが発生します。isset($obj->prop)で先に確認すればエラーにならず、安全に判定できます。 - マジックメソッド
__isset()が定義されたクラスでは挙動が変わる:オブジェクトに__isset()マジックメソッドが実装されている場合、プロパティが実際に存在しなくてもisset($obj->prop)の結果はそのメソッドのロジックに従います。フレームワークが提供するオブジェクト(Eloquentモデルなど)で意図しない結果になったときは、このマジックメソッドの実装を確認してください。
代替・関連APIとの比較
| 方法 | 向いている場面 | 特徴 |
|---|---|---|
isset($var) | 変数・配列キー・プロパティが「使える状態」かの確認 | 未定義でもエラーにならない。値がnullならfalse |
$var ?? $default | 値が無ければデフォルト値を使いたいだけのとき | isset()と同じ判定基準を1行で書ける。PHP 7.0以降 |
$var ??= $default | 未設定のときだけ変数に値を代入したいとき | 設定済みなら何もしない。PHP 7.4以降 |
empty($var) | 「空」かどうか(0や空文字も含めて)を判定したいとき | 未定義変数でもエラーにならない。empty関数の詳細を参照 |
array_key_exists('key', $arr) | 値がnullでも「キーの存在」自体を確認したいとき | 配列専用。連想配列に厳密なキー確認をしたい場合に使う |
property_exists($obj, 'prop') | 未初期化・privateなプロパティの存在確認 | 値を読まずに宣言の有無だけを確認できる |
トラブルシュート(症状別)
| 症状 | 原因 | 対処 |
|---|---|---|
| フォームで「0」や空文字を入力すると未入力扱いになる | isset()ではなくempty()で判定していて、0や""が空とみなされている | 「値が本当にセットされているか」を見たいならisset()、「実質的に空でないか」を見たいならempty()を使い分ける |
isset($arr['key'])がfalseなのにキーは存在すると言われる | そのキーにnullが代入されている | array_key_exists('key', $arr)でキー自体の有無を確認する |
isset(functionName())で構文エラーになる | isset()は言語構文であり、関数の戻り値を直接渡せない | 一度変数に代入してからisset($result)とするか、$result !== nullで判定する |
| オブジェクトのプロパティで「must not be accessed before initialization」エラーが出る | PHP 7.4以降の型付きプロパティが未初期化のまま直接アクセスされた | 直接アクセスする前にisset($obj->prop)で存在確認する |
Eloquentモデルの属性でisset()の結果が想定と違う | モデルの__isset()マジックメソッドの実装(アクセサやリレーションの遅延読み込みなど)が影響している | 属性名のtypoを確認するほか、必要ならarray_key_exists()や$model->attributesToArray()で実データを確認する |
よくある質問(FAQ)
Q. isset()とempty()はどちらを使えばいいですか?
A. 「変数が定義済みでnullでないか」を確認したいだけならisset()、「値が実質的に空(0・""・null・空配列など)でないか」まで含めて確認したいならempty()を使います。フォームの必須入力チェックのように「空文字も未入力扱いにしたい」場面ではempty()が適しています。
Q. isset()と??(null合体演算子)はどう使い分けますか?
A. 判定基準は同じです。「セットされていなければ処理を分岐する」ような複雑なロジックが必要ならif文でisset()を使い、「セットされていなければデフォルト値を使うだけ」ならより簡潔な??を使うのがおすすめです。
Q. isset($_GET[‘id’]) が常にfalseになるのはなぜですか?
A. リクエストにidパラメータが実際に含まれていない可能性が高いです。var_dump($_GET);で実際に送信されているキー名を確認してください。フォームのname属性のtypoや、GETとPOSTの取り違えもよくある原因です。
Q. Laravel(Bladeやコントローラ)でもこの記事のisset()をそのまま使えますか?
A. 素のPHPの構文なのでLaravel内でもそのまま使えます。ただし、Bladeテンプレートでは@issetディレクティブが用意されているため見た目がすっきりします。ルートパラメータやEloquentモデルでの活用例はLaravelでissetを効果的に活用する方法と実践例まとめで解説しています。
関連記事
- empty — 変数や式が「空」か(未定義/偽相当/空配列など)を判定する
- Laravelでissetを効果的に活用する方法と実践例まとめ
- Laravelでのnull判定方法まとめ:Eloquent、Blade、条件文の使い方ガイド
- PHPで配列に要素を追加する方法|末尾・先頭・途中の追加まとめ
参考リンク
- PHP公式マニュアル「isset」:https://www.php.net/manual/ja/function.isset.php
- PHP公式マニュアル「empty」:https://www.php.net/manual/ja/function.empty.php
- PHP公式マニュアル「array_key_exists」:https://www.php.net/manual/ja/function.array-key-exists.php
- PHP公式マニュアル「null合体演算子」:https://www.php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.coalesce

コメント