json_encode($value)は、PHPの値をJSONのテキストにして返します。連想配列はJSONオブジェクトに、リスト(キーが0, 1, 2...)はJSON配列になり、文字列、数値、true、false、nullはそれぞれ対応するJSONの値になります。
出力:
{"name":"Ada","age":36,"langs":["php","js"],"admin":true,"manager":null}
string
結果はただの文字列で、そのままブラウザに送ったり、ファイルやデータベースのカラムに保存したり、ほかのプログラムに渡したりできます。JSONをPHPに戻すにはjson_decode()を使います。
JSONを整形して出力する
json_encode()は2つ目の引数にフラグを受け取ります。JSON_PRETTY_PRINTは改行と4つの空白のインデントを加え、設定ファイルやデバッグ用のログに向いています。複数のフラグは|で組み合わせます。
出力:
{
"app": "shop",
"debug": false,
"db": {
"host": "localhost",
"port": 3306
},
"tags": []
}
日本語などのUTF-8テキストを読めるまま保つ
デフォルトでは、json_encode()はASCII以外のすべての文字を\uのエスケープで書き、すべての/の前にバックスラッシュを付けます。どちらも正しいJSONで、デコードすれば同じテキストに戻りますが、出力が読みにくく長くなります。JSON_UNESCAPED_UNICODEは文字をそのまま保ち、JSON_UNESCAPED_SLASHESはURLをそのまま保ちます。
出力:
{"name":"\u308a\u3093\u3054","price":120,"url":"https:\/\/example.com\/fruit\/apple"}
{"name":"りんご","price":120,"url":"https://example.com/fruit/apple"}
デコードしたあとに日本語が文字化けしているなら、原因はエスケープではなく、文字列がそもそもUTF-8ではなかったことです。json_encode()はUTF-8しか受け付けず、それ以外にはfalseを返します。エラーの節で示します。
配列がリストではなくオブジェクトになるとき
PHPの配列がJSON配列にエンコードされるのは、キーがちょうど0, 1, 2...と順に並んでいるときだけです。それ以外のキーではJSONオブジェクトになります。キーに欠番を残すunset()やarray_filter()のあとで、これに引っかかる人がよくいます。
出力:
{"0":"apple","2":"cherry"}
["apple","cherry"]
{"1":"a","2":"b"}
[]
{}
{"0":"a","1":"b"}
受け取る側のコードがリストを期待しているなら、エンコードする前に必ずarray_values()を呼びましょう。空かもしれないオブジェクトを期待しているなら、空の値でも{}として出力されるようnew stdClass()か(object) $arrayを使います。
オブジェクトをエンコードし、JsonSerializableでJSONを制御する
普通のオブジェクトはpublicなプロパティだけでエンコードされ、protectedとprivateのものは飛ばされます。オブジェクトがJSONでどう見えるかを正確に決めるには、JsonSerializableインターフェースを実装し、jsonSerialize()からデータを返します。
出力:
{"name":"Ada","nick":null}
{"date":"2026-03-14 09:30:00.000000","timezone_type":3,"timezone":"UTC"}
{
"id": 7,
"total": 19.5,
"created": "2026-03-14T09:30:00+00:00"
}
enum Status: stringのようなBacked Enumはその値("active")としてエンコードされます。Pure Enumには値がないので、json_encode()は「Non-backed enums have no default serialization」で失敗します。
数値、浮動小数点数、数値文字列
整数と浮動小数点数はJSONの数値として書かれ、文字列は数字を含んでいても文字列のままです。3つのフラグでこれを変えられます。
出力:
{"price":10}
{"price":10.0}
0.30000000000000004
{"qty":"3","id":"007"}
{"qty":3,"id":7}
JSON_NUMERIC_CHECKはすべての数値文字列を変換するので、"007"のようなIDや"01234"のような郵便番号は先頭のゼロを失います。配列全体にこれを使うのではなく、意図したフィールドを(int)で変換しましょう。
json_encodeがfalseを返す:エラーを見つける
値をエンコードできないと、json_encode()はfalseを返します。よくある原因は、正しいUTF-8でない文字列(古いファイルやLatin-1のデータベースから読んだテキスト)と、浮動小数点数の値NANとINFです。json_last_error_msg()が何が問題かを示し、JSON_THROW_ON_ERRORを指定すると代わりにJsonExceptionが投げられます。
出力:
bool(false)
Malformed UTF-8 characters, possibly incorrectly encoded
{"name":"Caf\ufffd"}
{"name":"Café"}
JsonException: Inf and NaN cannot be JSON encoded
新しいコードではJSON_THROW_ON_ERRORのほうがよいデフォルトです。誰も確認しないfalseは、空文字列として保存されたり送信されたりしてしまいます。
PHPのAPIからJSONを返す
JSONで応答するPHPスクリプトは、何かを出力する前にContent-Typeヘッダーを設定し、1回だけエンコードして終了します。
<?php
header('Content-Type: application/json; charset=utf-8');
$products = [
['id' => 1, 'name' => 'りんご', 'price' => 120],
['id' => 2, 'name' => 'みかん', 'price' => 80],
];
echo json_encode(['data' => $products], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
exit;
代わりにHTMLの<script>タグの中にJSONを出力するときは、JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOTを加えます。デフォルトのスラッシュのエスケープは</script>を<\/script>に変えますが、誰かがJSON_UNESCAPED_SLASHESを加えたとたんにその保護はなくなり、値の中の<!--はやはりブラウザのスクリプトの解析を変えてしまいます。これらのフラグは<、>、&、'、"を\u003C、\u003E、\u0026、\u0027、\u0022として書き、JavaScriptはそれを同じ文字として読み戻します。
よくある質問
PHPの配列をJSONに変換するには?
json_encode()に渡します:json_encode(['name' => 'Ada', 'age' => 36])は{"name":"Ada","age":36}を返します。キーが0, 1, 2...と順に並ぶ配列は、代わりにJSON配列になります:json_encode(['a', 'b'])は["a","b"]を返します。
PHPでJSONを整形して出力するには?
JSON_PRETTY_PRINTフラグを加えます:json_encode($data, JSON_PRETTY_PRINT)は4つの空白でインデントし、各値を1行ずつに置きます。フラグは|で組み合わせます。たとえばJSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODEです。
json_encodeで日本語が\uのコードになってしまうのはなぜですか?
デフォルトでは、ASCII以外のすべての文字が\uXXXXのエスケープで書かれるので、りんごは\u308a\u3093\u3054になります。それでも正しいJSONですが、文字を読めるまま保つにはJSON_UNESCAPED_UNICODEを渡します。
json_encodeがfalseを返すのはなぜですか?
たいていは、文字列が正しいUTF-8でないか、データにNANやINFが含まれているからです。json_last_error_msg()を呼んで理由を確認するか、falseを返す代わりにJsonExceptionを投げるようJSON_THROW_ON_ERRORを渡します。
空の配列に対してjson_encodeに[]ではなく{}を出力させるには?
PHPの空の配列は常に[]にエンコードされます。空のオブジェクトにはnew stdClass()か(object) []を使うか、値の中のすべての配列をオブジェクトにするJSON_FORCE_OBJECTフラグを使います。