サーチ…


前書き

JSONJavaScript 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標準の一部ではありません。その結果、 JSLintJSON 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"

falsenullについても同様の動作が発生し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演算子|

PHP 5.x 5.3

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_TAGJSON_HEX_AMPJSON_HEX_APOSJSON_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"}
PHP 5.x 5.3

JSON_NUMERIC_CHECK

数値文字列が整数に変換されるようにします。

$array = ['23452', 23452];
echo json_encode($array);
echo json_encode($array, JSON_NUMERIC_CHECK);

出力:

["23452",23452]    
[23452,23452]
PHP 5.x 5.4

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"}
PHP 5.x 5.5

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"}
PHP 5.x 5.6

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]
PHP 7.x 7.1

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の使用

PHP 5.x 5.4

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);
    });


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow