【PHP8.x】JSON_ERROR_INF_OR_NAN定数の使い方
JSON_ERROR_INF_OR_NAN定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
JSON_ERROR_INF_OR_NAN定数は、PHPでJSONデータを扱う際に発生する特定のエンコードエラーを表す定数です。JSON(JavaScript Object Notation)は、Webアプリケーションなどでデータのやり取りに広く利用される軽量なデータ形式ですが、その標準仕様には表現できない特定の数値が存在します。
この定数が示すエラーは、無限大(infinity、PHPではINFとして表現されます)や非数(Not a Number、PHPではNANとして表現されます)といった特殊な数値が、JSONデータに変換されようとした場合に発生します。JSONの標準仕様では、無限大や非数を直接表現する方法が定義されていないため、PHPのjson_encode()関数などでこれらの特殊な数値を含むデータをJSON形式に変換しようとすると、このJSON_ERROR_INF_OR_NANエラーが発生します。
例えば、ゼロ除算によって得られる無限大の値や、無効な数学演算の結果として生じる非数の値をJSON文字列に変換しようとした際、json_encode()は失敗し、そのエラーの種類をjson_last_error()関数で確認すると、この定数が返されます。
システムエンジニアは、この定数を利用してJSON変換時のエラーを具体的に特定し、アプリケーションの堅牢性を高めることができます。このエラーを受け取った際には、JSONに変換する前のデータに無限大や非数が含まれていないかを確認し、必要に応じてこれらの値を事前に処理したり、他の形式に置き換えたりするなどの対策を講じることが重要です。
構文(syntax)
1if (json_last_error() === JSON_ERROR_INF_OR_NAN) { 2 // ... 3}
引数(parameters)
引数なし
引数はありません
戻り値(return)
int
JSON_ERROR_INF_OR_NANは、JSONエンコード中に無限大またはNaN(非数)の値が含まれていた場合に発生するエラーコードを表す整数値です。
サンプルコード
PHP JSONエラー処理: INF/NANとNONE
1<?php 2 3/** 4 * JSONエンコード時のエラー処理、特に無限大(INF)や非数(NAN)が含まれる場合の 5 * JSON_ERROR_INF_OR_NAN の発生と、エラーがない場合の JSON_ERROR_NONE の検出方法を示します。 6 * システムエンジニアを目指す初心者向けに、基本的なJSONエラーのチェック方法を解説します。 7 */ 8function demonstrateJsonInfOrNanErrorHandling(): void 9{ 10 echo "--- ケース1: JSON_ERROR_INF_OR_NAN の発生 ---" . PHP_EOL; 11 12 // 無限大 (INF) を含むデータ配列を準備 13 // JSONは数値として無限大や非数を直接表現できないため、エンコード時にエラーとなります。 14 $dataWithInf = [ 15 'itemName' => 'Product A', 16 'price' => 99.99, 17 'rating' => INF, // ここで無限大 (Infinity) を含めます 18 'tags' => ['electronics', 'gadget'] 19 ]; 20 21 echo "エンコードを試みるデータ (無限大を含む): " . print_r($dataWithInf, true) . PHP_EOL; 22 23 // データをJSON形式にエンコードを試みる 24 // PHP 7.3以降では、INF/NANが含まれるとjson_encodeはデフォルトでfalseを返し、エラーをセットします。 25 $jsonEncodedInf = json_encode($dataWithInf); 26 27 // json_last_error() で最後に発生したJSONエラーコードを取得 28 $errorCodeInf = json_last_error(); 29 // json_last_error_msg() で最後に発生したJSONエラーメッセージを取得 30 $errorMessageInf = json_last_error_msg(); 31 32 // エラーコードが JSON_ERROR_INF_OR_NAN と一致するか確認 33 if ($errorCodeInf === JSON_ERROR_INF_OR_NAN) { 34 echo "-> エラー検出: JSON_ERROR_INF_OR_NAN が発生しました。" . PHP_EOL; 35 echo " エラーコード: " . $errorCodeInf . PHP_EOL; // JSON_ERROR_INF_OR_NAN の数値 36 echo " エラーメッセージ: " . $errorMessageInf . PHP_EOL; 37 echo " json_encode() の結果: " . ($jsonEncodedInf === false ? "失敗 (false)" : $jsonEncodedInf) . PHP_EOL; 38 } elseif ($errorCodeInf !== JSON_ERROR_NONE) { 39 // その他のJSONエラーが発生した場合 40 echo "-> その他のJSONエラーが発生しました。" . PHP_EOL; 41 echo " エラーコード: " . $errorCodeInf . PHP_EOL; 42 echo " エラーメッセージ: " . $errorMessageInf . PHP_EOL; 43 echo " json_encode() の結果: " . ($jsonEncodedInf === false ? "失敗 (false)" : $jsonEncodedInf) . PHP_EOL; 44 } else { 45 // 予期せずエラーが発生しなかった場合(通常はここには来ない) 46 echo "-> エラーは発生しませんでした (予期せぬ結果)。" . PHP_EOL; 47 echo " json_encode() の結果: " . $jsonEncodedInf . PHP_EOL; 48 } 49 50 echo PHP_EOL; 51 52 echo "--- ケース2: JSON_ERROR_NONE (エラーなし) の発生 ---" . PHP_EOL; 53 54 // 正常なデータ配列を準備 (無限大や非数を含まない) 55 $normalData = [ 56 'itemName' => 'Product B', 57 'price' => 19.99, 58 'stock' => 150, 59 'available' => true 60 ]; 61 62 echo "エンコードを試みるデータ (正常): " . print_r($normalData, true) . PHP_EOL; 63 64 // 正常なデータをJSON形式にエンコード 65 $jsonEncodedNormal = json_encode($normalData); 66 67 // json_last_error() で最後に発生したJSONエラーコードを取得 68 $errorCodeNormal = json_last_error(); 69 // json_last_error_msg() で最後に発生したJSONエラーメッセージを取得 70 $errorMessageNormal = json_last_error_msg(); 71 72 // エラーコードが JSON_ERROR_NONE (エラーなし) と一致するか確認 73 if ($errorCodeNormal === JSON_ERROR_NONE) { 74 echo "-> エラーは発生しませんでした: JSON_ERROR_NONE が検出されました。" . PHP_EOL; 75 echo " エラーコード: " . $errorCodeNormal . PHP_EOL; // JSON_ERROR_NONE の数値 76 echo " json_encode() の結果: " . $jsonEncodedNormal . PHP_EOL; 77 } else { 78 // 予期せぬJSONエラーが発生した場合 79 echo "-> 予期せぬJSONエラーが発生しました。" . PHP_EOL; 80 echo " エラーコード: " . $errorCodeNormal . PHP_EOL; 81 echo " エラーメッセージ: " . $errorMessageNormal . PHP_EOL; 82 echo " json_encode() の結果: " . ($jsonEncodedNormal === false ? "失敗 (false)" : $jsonEncodedNormal) . PHP_EOL; 83 } 84} 85 86// 関数を実行して動作を確認します 87demonstrateJsonInfOrNanErrorHandling(); 88
このサンプルコードは、PHPでJSONデータを扱う際に発生する可能性のあるエラー、特に無限大(INF)や非数(NAN)を含むデータをエンコードしようとしたときに検出されるJSON_ERROR_INF_OR_NANの扱い方と、エラーが全くないことを示すJSON_ERROR_NONEの検出方法を、システムエンジニアを目指す初心者向けに解説しています。
JSON_ERROR_INF_OR_NANは、JSON形式が直接表現できない無限大(INF)や非数(NAN)といった特殊な数値がPHPのデータ構造に含まれている場合に、json_encode()関数がそのデータをJSON文字列に変換できなかったことを示す定数です。この定数自体には引数はなく、その値はPHP内部で定義された整数値(int)として利用されます。
コードの「ケース1」では、無限大(INF)を含む配列をjson_encode()で変換しようとします。json_encode()はエラーが発生するとfalseを返し、その直後にjson_last_error()関数を呼び出すことで、最後に発生したJSONエラーのコード(整数値)を取得できます。このコードがJSON_ERROR_INF_OR_NANと一致すれば、特定の無限大/非数エラーが発生したと判断できます。さらに、json_last_error_msg()関数でエラーメッセージも確認できます。
一方、「ケース2」では、正常なデータ配列をjson_encode()で変換します。この場合、json_last_error()はエラーが一つも発生しなかったことを示すJSON_ERROR_NONEという定数を返します。これは、データのJSON変換が成功したことを確認する際に非常に重要なチェックポイントとなります。
このように、json_last_error()とこれらの定数を活用することで、PHPでのJSON処理におけるエラーを正確に特定し、適切なエラーハンドリングを行うための基礎を学ぶことができます。
json_encode関数がfalseを返した場合、それはエンコードが失敗したことを意味しますが、具体的なエラー原因は不明です。そのため、必ずjson_last_error()関数でエラーコードを取得し、JSON_ERROR_INF_OR_NANなどの定数と比較して、何が問題だったのかを特定することが重要です。特に無限大(INF)や非数(NAN)はJSON形式では直接表現できないため、これらの値がデータに含まれるとJSON_ERROR_INF_OR_NANが発生し、エンコードは失敗します。エラーがない場合はJSON_ERROR_NONEが検出できるため、常にエンコードの成功・失敗を明示的にチェックする習慣をつけ、アプリケーションの安定性を高めましょう。
PHP JSONエラー: INF/NaNエンコード失敗
1<?php 2 3/** 4 * PHPのJSON関連のエラー定数 JSON_ERROR_INF_OR_NAN の発生と検出をデモンストレーションします。 5 * 6 * このエラーは、json_encode() が無限大 (INF) または非数 (NaN) の値を 7 * JSONに変換しようとしたときに発生します。JSON標準はこれらの値をサポートしていません。 8 */ 9function demonstrateJsonErrorInfOrNan(): void 10{ 11 // 無限大 (INF) と非数 (NaN) を含む配列を準備します。 12 $dataWithSpecialFloats = [ 13 'normal_number' => 123.45, 14 'positive_infinity' => INF, // 無限大 15 'not_a_number' => NAN, // 非数 16 'another_number' => 67.89, 17 ]; 18 19 echo "--- JSON_ERROR_INF_OR_NAN デモンストレーション ---\n\n"; 20 echo "JSONエンコードを試みるデータ:\n"; 21 print_r($dataWithSpecialFloats); 22 23 // データをJSON形式にエンコードします。 24 // INFやNANが含まれる場合、json_encode() はデフォルトで false を返します。 25 $jsonEncodedData = json_encode($dataWithSpecialFloats); 26 27 echo "\njson_encode() の結果: " . var_export($jsonEncodedData, true) . "\n"; 28 29 // json_last_error() を使用して、最後に発生したJSONエラーコードを取得します。 30 $lastJsonError = json_last_error(); 31 32 echo "\n最後に発生したJSONエラーコード: " . $lastJsonError . "\n"; 33 34 // エラーコードが JSON_ERROR_INF_OR_NAN と一致するか確認します。 35 if ($lastJsonError === JSON_ERROR_INF_OR_NAN) { 36 echo "エラータイプ: JSON_ERROR_INF_OR_NAN\n"; 37 echo "説明: JSONは標準で無限大(INF)や非数(NaN)を表現できないため、エンコードに失敗しました。\n"; 38 echo " これは、JSON_ERROR_INF_OR_NAN 定数が示すエラーです。\n"; 39 } elseif ($lastJsonError !== JSON_ERROR_NONE) { 40 // その他のエラーが発生した場合 41 echo "その他のJSONエラーが発生しました。エラーコード: " . $lastJsonError . "\n"; 42 echo "エラーメッセージ: " . json_last_error_msg() . "\n"; 43 } else { 44 echo "JSONエンコードは成功しました。\n"; 45 } 46} 47 48// 関数を実行してデモンストレーションを開始します。 49demonstrateJsonErrorInfOrNan();
PHP 8で導入されたJSON_ERROR_INF_OR_NANは、JSONのエンコード処理に関するエラーを示す定数です。この定数は、json_encode()関数が、無限大(INF)や非数(NaN)といった特殊な浮動小数点数をJSON形式に変換しようとした際に発生します。JSON標準はこれらの値を直接サポートしていないため、エンコードが失敗した場合にこのエラーコードが返されます。
この定数は引数を取らず、エラーの種類を識別するための整数値(int)を返します。サンプルコードでは、無限大と非数を含む配列をjson_encode()で処理しようとします。通常、このようなデータが含まれるとjson_encode()はfalseを返します。その直後にjson_last_error()関数を呼び出すことで、最後に発生したJSONエラーのコードを取得できます。取得されたエラーコードがJSON_ERROR_INF_OR_NANと一致すれば、無限大または非数の値が原因でエンコードに失敗したことがわかります。この定数を利用することで、JSONエンコードの失敗原因を正確に特定し、適切なエラーハンドリングを行うことが可能になります。
json_encode()は処理に失敗するとfalseを返すため、必ず戻り値を確認してください。falseが返された場合は、json_last_error()でエラーコードを取得し、json_last_error_msg()で詳細なエラーメッセージを確認することが大切です。JSON_ERROR_INF_OR_NANは、JSONの仕様上、無限大(INF)や非数(NaN)の値を直接表現できないために発生します。これらの値を含めてJSONに変換したい場合は、事前に文字列として扱うなどの工夫が必要です。PHP 7.3以降では、json_encode()にJSON_THROW_ON_ERRORオプションを渡すことで、エラーを例外として捕捉し、より安全に処理することも可能です。