サーチ…
前書き
JSON ( JavaScript Object Notation )は、オブジェクトをプレーンテキストにシリアル化するプラットフォームおよび言語に依存しない方法です。 PHPはWeb上でよく使われるため、PHPでJSONを使うための基本的な拡張があります。
構文
- 文字列json_encode(mixed $ value [、int $ options = 0 [、int $ depth = 512]])
- 混合json_decode(文字列$ json [、bool $ assoc = false [、int $ depth = 512 [、int $ options = 0]]])
パラメーター
パラメータ | 詳細 |
---|---|
json_encode | - |
値 | 値がエンコードされています。リソース以外の任意のタイプにすることができます。すべての文字列データはUTF-8でエンコードされている必要があります。 |
オプション | ビットマスクは、JSON_HEX_QUOT、JSON_HEX_TAG、JSON_HEX_APOS、JSON_HEX_APOS、JSON_NUMERIC_CHECK、JSON_PRETTY_PRINT、JSON_UNESCAPED_SLASHES、JSON_FORCE_OBJECT、JSON_PRESERVE_ZERO_FRACTION、JSON_UNESCAPED_UNICODE、JSON_PARTIAL_OUTPUT_ON_ERRORで構成されます。これらの定数の動作は、 JSON定数ページで説明しています。 |
深さ | 最大深度を設定します。ゼロより大きくなければなりません。 |
json_decode | - |
ジョソン | json文字列がデコードされています。この関数は、UTF-8でエンコードされた文字列でのみ機能します。 |
アソーク | オブジェクトの代わりに連想配列を返さなければなりません。 |
オプション | JSONデコードオプションのビットマスク。現在、JSON_BIGINT_AS_STRINGのみがサポートされています(デフォルトでは、大きな整数を浮動小数点数としてキャストします) |
備考
- 無効なJSONのjson_decode処理は非常に不安定であり、デコードが成功したかどうかを確実に判断することは非常に困難です.json_decodeは無効な入力に対してもnullを返します。 このような問題を防ぐためには、毎回json_last_errorを使用する必要があります。
JSON文字列をデコードする
json_decode()
関数はJSONでエンコードされた文字列を最初のパラメータとして取り、それをPHP変数に解析します。
通常、 json_decode()
は、JSONオブジェクトの最上位項目がディクショナリである場合は\ stdClassのオブジェクトを返し、JSONオブジェクトが配列の場合はインデックス付き配列を返します 。また、スカラー値、または単純な文字列"true"
、 "false"
、 "null"
などのスカラー値については、スカラー値またはNULL
を戻しNULL
。また、エラー時にNULL
を返しNULL
。
// Returns an object (The top level item in the JSON string is a JSON dictionary)
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$object = json_decode($json_string);
printf('Hello %s, You are %s years old.', $object->name, $object->age);
#> Hello Jeff, You are 20 years old.
// Returns an array (The top level item in the JSON string is a JSON array)
$json_string = '["Jeff", 20, true, ["red", "blue"]]';
$array = json_decode($json_string);
printf('Hello %s, You are %s years old.', $array[0], $array[1]);
上記でデコードしたオブジェクトの各プロパティの型と値を表示するには、 var_dump()
を使用します。
// Dump our above $object to view how it was decoded
var_dump($object);
出力(変数の種類に注意してください):
class stdClass#2 (4) {
["name"] => string(4) "Jeff"
["age"] => int(20)
["active"] => bool(true)
["colors"] =>
array(2) {
[0] => string(3) "red"
[1] => string(4) "blue"
}
}
注: JSONの変数型は、PHP同等のものに変換されました。
オブジェクトを返す代わりにJSONオブジェクトの連想配列を返すには、 json_decode()
2番目のパラメータとしてtrue
を渡しtrue
。
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$array = json_decode($json_string, true); // Note the second parameter
var_dump($array);
出力(配列連想構造に注意してください):
array(4) {
["name"] => string(4) "Jeff"
["age"] => int(20)
["active"] => bool(true)
["colors"] =>
array(2) {
[0] => string(3) "red"
[1] => string(4) "blue"
}
}
返される変数がオブジェクトでない場合、2番目のパラメータ( $assoc
)は無効です。
注意: $assoc
パラメータを使用すると、空の配列と空のオブジェクトの区別が失われます。つまり、デコードされた出力に対してjson_encode()
を実行すると、別のJSON構造になります。
json_decode()
関数は、再帰的にJSON文字列が512以上の要素( 5.2.3より前のバージョンでは20要素、バージョン5.2.3では128要素)の「深さ」を持つ場合、 NULL
返しNULL
。バージョン5.3以降では、この制限は、後述するように、第3パラメータ( $depth
)を使用して制御できます。
マニュアルによると:
PHPはオリジナルのRFC 4627で指定されているJSONのスーパーセットを実装しています。スカラー型とNULLをエンコードしてデコードします。 RFC 4627は、配列またはオブジェクトの内部にネストされている場合にのみ、これらの値をサポートします。このスーパーセットは、より新しい»RFC 7159 (RFC 4627に取って替わることを目指す)と»ECMA-404の JSONテキストの拡張された定義と一致しますが、これはRFC 4627を厳密に遵守する古いJSONパーサーとの相互運用性の問題を引き起こす可能性があります。単一のスカラー値をエンコードします。
つまり、たとえば、単純な文字列はPHPで有効なJSONオブジェクトと見なされます。
$json = json_decode('"some string"', true);
var_dump($json, json_last_error_msg());
出力:
string(11) "some string"
string(8) "No error"
しかし配列やオブジェクトではなく、単純な文字列はRFC 4627標準の一部ではありません。その結果、 JSLint 、 JSON Formatter&Validator (RFC 4627モード)などのオンラインチェッカーでエラーが発生します。
再帰の深$depth
3番目の$depth
パラメータ(デフォルト値は512
)があります。これは、元のオブジェクトの中に入れ子にされたオブジェクトのデコード量を意味します。
4番目の$options
パラメータが$options
ます。現在、1つの値JSON_BIGINT_AS_STRING
のみを受け入れます。デフォルトの動作(このオプションを省略)は、大きな整数を文字列の代わりに浮動小数点数にキャストすることです。
true、false、およびnullリテラルの無効でない小文字でないバリアントは、もはや有効な入力として受け入れられません。
したがって、この例:
var_dump(json_decode('tRue'), json_last_error_msg());
var_dump(json_decode('tRUe'), json_last_error_msg());
var_dump(json_decode('tRUE'), json_last_error_msg());
var_dump(json_decode('TRUe'), json_last_error_msg());
var_dump(json_decode('TRUE'), json_last_error_msg());
var_dump(json_decode('true'), json_last_error_msg());
PHP 5.6より前:
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
以降:
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
bool(true)
string(8) "No error"
false
とnull
についても同様の動作が発生しnull
。
文字列が変換できない場合、 json_decode()
はNULL
を返しNULL
。
$json = "{'name': 'Jeff', 'age': 20 }" ; // invalid json
$person = json_decode($json);
echo $person->name; // Notice: Trying to get property of non-object: returns null
echo json_last_error();
# 4 (JSON_ERROR_SYNTAX)
echo json_last_error_msg();
# unexpected character
エラーを検出するためにNULL
を返すだけでは安全ではありません。たとえば、JSON文字列に"null"
以外が含まれている場合、 json_decode()
はエラーが発生していなくてもnull
を返しnull
。
JSON文字列のエンコーディング
json_encode
関数は、PHP配列(またはPHP 5.4以降、 JsonSerializable
インタフェースを実装するオブジェクト)をJSONエンコード文字列に変換します。成功した場合はJSONエンコードされた文字列を返し、失敗した場合はFALSEを返します。
$array = [
'name' => 'Jeff',
'age' => 20,
'active' => true,
'colors' => ['red', 'blue'],
'values' => [0=>'foo', 3=>'bar'],
];
エンコーディング中にPHPのデータ型文字列、整数、ブール値はJSONに相当するものに変換されます。連想配列はJSONオブジェクトとしてエンコードされます。デフォルトの引数で呼び出されると、インデックス配列はJSON配列としてエンコードされます。 (配列キーが0から始まる連続した数値シーケンスでない場合は、配列はJSONオブジェクトとしてエンコードされます)。
echo json_encode($array);
出力:
{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}
引数
PHP 5.3以降、 json_encode
の第2引数はビットマスクです。このビットマスクは、次のうちの1つ以上になります。
任意のビットマスクと同様に、2進のOR演算子|
。
JSON_FORCE_OBJECT
配列の代わりにオブジェクトを強制的に作成する
$array = ['Joel', 23, true, ['red', 'blue']];
echo json_encode($array);
echo json_encode($array, JSON_FORCE_OBJECT);
出力:
["Joel",23,true,["red","blue"]]
{"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}
JSON_HEX_TAG
、 JSON_HEX_AMP
、 JSON_HEX_APOS
、 JSON_HEX_QUOT
エンコーディング中に以下の変換を保証します。
定数 | 入力 | 出力 |
---|---|---|
JSON_HEX_TAG | < | \u003C |
JSON_HEX_TAG | > | \u003E |
JSON_HEX_AMP | & | \u0026 |
JSON_HEX_APOS | ' | \u0027 |
JSON_HEX_QUOT | " | \u0022 |
$array = ["tag"=>"<>", "amp"=>"&", "apos"=>"'", "quot"=>"\""];
echo json_encode($array);
echo json_encode($array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
出力:
{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
JSON_NUMERIC_CHECK
数値文字列が整数に変換されるようにします。
$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);
出力:
["23452",23452]
[23452,23452]
JSON_PRETTY_PRINT
JSONを読みやすくします
$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);
出力:
{"a":1,"b":2,"c":3,"d":4}
{
"a": 1,
"b": 2,
"c": 3,
"d": 4
}
JSON_UNESCAPED_SLASHES
出力にエスケープされていない/
スラッシュが含まれています
$array = ['filename' => 'example.txt', 'path' => '/full/path/to/file/'];
echo json_encode($array);
echo json_encode($array, JSON_UNESCAPED_SLASHES);
出力:
{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}
JSON_UNESCAPED_UNICODE
出力にUTF-8でエンコードされた文字を\u
エンコードされた文字列の代わりに出力します
$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);
出力:
{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
JSON_PARTIAL_OUTPUT_ON_ERROR
エンコードできない値がある場合、エンコードを続行できます。
$fp = fopen("foo.txt", "r");
$array = ["file"=>$fp, "name"=>"foo.txt"];
echo json_encode($array); // no output
echo json_encode($array, JSON_PARTIAL_OUTPUT_ON_ERROR);
出力:
{"file":null,"name":"foo.txt"}
JSON_PRESERVE_ZERO_FRACTION
浮動体が浮動小数点として常に符号化されるようにします。
$array = [5.0, 5.5];
echo json_encode($array);
echo json_encode($array, JSON_PRESERVE_ZERO_FRACTION);
出力:
[5,5.5]
[5.0,5.5]
JSON_UNESCAPED_LINE_TERMINATORS
JSON_UNESCAPED_UNICODE
とともに使用すると、古いPHPバージョンの動作に戻り、U + 2028 LINE SEPARATORおよびU + 2029 PARAGRAPH SEPARATORの文字をエスケープしません 。 JSONでは有効ですが、これらの文字はJavaScriptでは無効です。したがって、バージョン7.1 JSON_UNESCAPED_UNICODE
のデフォルト動作が変更されました。
$array = ["line"=>"\xe2\x80\xa8", "paragraph"=>"\xe2\x80\xa9"];
echo json_encode($array, JSON_UNESCAPED_UNICODE);
echo json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);
出力:
{"line":"\u2028","paragraph":"\u2029"}
{"line":"
","paragraph":"
"}
JSONエラーのデバッグ
json_encode
またはjson_decode
が指定された文字列の解析に失敗すると、 false
を返しfalse
。この問題が発生したとき、PHP自体が責任を使用するユーザーにあり、エラーや警告は発生しませんjson_last_error()とjson_last_error_msg()エラーが発生したかどうかを確認し、それをデバッグ(アプリケーションに応じて行動すると、エラーメッセージを表示する機能を、など)。
次の例は、JSONを操作する際の一般的なエラーを示しています( JSON文字列のデコード/エンコードに失敗した場合など) 。
// An incorrectly formed JSON string
$jsonString = json_encode("{'Bad JSON':\xB1\x31}");
if (json_last_error() != JSON_ERROR_NONE) {
printf("JSON Error: %s", json_last_error_msg());
}
#> JSON Error: Malformed UTF-8 characters, possibly incorrectly encoded
json_last_error_msg
json_last_error_msg()
は、文字列をエンコード/デコードしようとしたときに発生した、最後に発生したエラーの人間が読めるメッセージを返します。
- エラーが発生していなくても、この関数は常に文字列を返します。
デフォルトの非エラー文字列はNo Error
- 他の(未知の)エラーが発生した場合は
false
を返しfalse
- json_last_error_msgは各反復でオーバーライドされるため、このループでは注意が必要です。
この関数を使用して、表示するメッセージを取得し、制御ステートメントではテストしないでください。
// Don't do this:
if (json_last_error_msg()){} // always true (it's a string)
if (json_last_error_msg() != "No Error"){} // Bad practice
// Do this: (test the integer against one of the pre-defined constants)
if (json_last_error() != JSON_ERROR_NONE) {
// Use json_last_error_msg to display the message only, (not test against it)
printf("JSON Error: %s", json_last_error_msg());
}
この関数は、PHP 5.5より前には存在しません。ここにpolyfill実装があります:
if (!function_exists('json_last_error_msg')) {
function json_last_error_msg() {
static $ERRORS = array(
JSON_ERROR_NONE => 'No error',
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
);
$error = json_last_error();
return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
}
}
json_last_error
json_last_error()
は、PHPが提供する定義済みの定数の1つにマップされた整数を返します。
定数 | 意味 |
---|---|
JSON_ERROR_NONE | エラーは発生していません |
JSON_ERROR_DEPTH | 最大スタック深度を超えました |
JSON_ERROR_STATE_MISMATCH | 無効なJSONまたは不正な形式のJSON |
JSON_ERROR_CTRL_CHAR | 制御文字エラー、おそらく正しくエンコードされていない |
JSON_ERROR_SYNTAX | 構文エラー(PHP 5.3.3以降) |
JSON_ERROR_UTF8 | 不正な形式のUTF-8文字(PHP 5.5.0以降) |
JSON_ERROR_RECURSION | エンコードされる値の1つ以上の再帰的参照 |
JSON_ERROR_INF_OR_NAN | エンコードされる値の1つ以上のNANまたはINF値 |
JSON_ERROR_UNSUPPORTED_TYPE | エンコードできない型の値が与えられました |
オブジェクトでのJsonSerializableの使用
REST APIを構築するときは、クライアントアプリケーションに渡すオブジェクトの情報を減らす必要があります。この目的のために、この例ではJsonSerialiazble
インターフェイスを使用する方法を示します。
この例では、クラスUser
実際にはhypotetical ORMのDBモデルオブジェクトを拡張しています。
class User extends Model implements JsonSerializable {
public $id;
public $name;
public $surname;
public $username;
public $password;
public $email;
public $date_created;
public $date_edit;
public $role;
public $status;
public function jsonSerialize() {
return [
'name' => $this->name,
'surname' => $this->surname,
'username' => $this->username
];
}
}
jsonSerialize()
メソッドを提供して、クラスにJsonSerializable
実装を追加します。
public function jsonSerialize()
アプリケーションのコントローラまたはスクリプトで、オブジェクトUserをjson_encode()
に渡すと、オブジェクト全体ではなくjsonSerialize()
メソッドのjson encoded配列が返されます。
json_encode($User);
戻ります:
{"name":"John", "surname":"Doe", "username" : "TestJson"}
プロパティ値の例
これにより、RESTfulなエンドポイントから返されるデータ量が削減され、json表現からオブジェクトプロパティを除外できます。
json_encode()
でのプライベートプロパティとプロテクトプロパティの使用
JsonSerializableの使用を避けるために、privateまたはprotectedプロパティを使用してjson_encode()
出力からクラス情報を隠すこともできます。クラスは\ JsonSerializableを実装する必要はありません。
json_encode()関数は、クラスのパブリックプロパティをJSONにエンコードします。
<?php
class User {
// private properties only within this class
private $id;
private $date_created;
private $date_edit;
// properties used in extended classes
protected $password;
protected $email;
protected $role;
protected $status;
// share these properties with the end user
public $name;
public $surname;
public $username;
// jsonSerialize() not needed here
}
$theUser = new User();
var_dump(json_encode($theUser));
出力:
string(44) "{"name":null,"surname":null,"username":null}"
ヘッダーjsonと返された応答
コンテンツタイプのヘッダーをJSONとして追加すると:
<?php
$result = array('menu1' => 'home', 'menu2' => 'code php', 'menu3' => 'about');
//return the json response :
header('Content-Type: application/json'); // <-- header declaration
echo json_encode($result, true); // <--- encode
exit();
ヘッダーがあるので、返されたデータとそのデータを処理する方法をアプリが検出できます。
コンテンツヘッダーは返されるデータの種類に関する情報に過ぎないことに注意してください 。
UTF-8を使用している場合は、次を使用できます。
header("Content-Type: application/json;charset=utf-8");
例jQuery:
$.ajax({
url:'url_your_page_php_that_return_json'
}).done(function(data){
console.table('json ',data);
console.log('Menu1 : ', data.menu1);
});