この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:atom
更新日時:2026-06-11 07:07:02

タイトル: 配列からJSONに変換
SEOタイトル: PHP 配列→JSON 変換 (json_encode) 完全ガイド(フラグ / UTF-8 / json_last_error)

この記事の要点
  • json_encode($array) が基本。連想配列 → JSON Object、index 配列 → JSON Array
  • 日本語文字化け対策: JSON_UNESCAPED_UNICODE フラグで Unicode をそのまま出力
  • スラッシュ / をエスケープしない: JSON_UNESCAPED_SLASHES
  • 整形出力: JSON_PRETTY_PRINT
  • PHP 7.3+ は JSON_THROW_ON_ERROR で例外化推奨
  • UTF-8 必須 (SJIS / EUC-JP は mb_convert_encoding() で先に変換)

基本: 配列を JSON 文字列に変換

 '山田太郎',
    'age'  => 30,
    'tags' => ['php', 'javascript'],
];

echo json_encode($data);
// → {"name":"山田太郎","age":30,"tags":["php","javascript"]}
//   日本語が \uXXXX エスケープされてしまう

echo json_encode($data, JSON_UNESCAPED_UNICODE);
// → {"name":"山田太郎","age":30,"tags":["php","javascript"]}
//   そのまま日本語で出る (推奨)

主要フラグ一覧

フラグ意味定番
JSON_UNESCAPED_UNICODE日本語等を \uXXXX にエスケープしない
JSON_UNESCAPED_SLASHES/ をエスケープしない (URL を含む時)
JSON_PRETTY_PRINT整形 (改行 + インデント)デバッグ用
JSON_THROW_ON_ERRORエラー時に JsonException 投げる (PHP 7.3+)★ 必須
JSON_NUMERIC_CHECK数値文字列を数値に変換 (危険)非推奨
JSON_FORCE_OBJECT空配列も {} として出力状況による
JSON_PRESERVE_ZERO_FRACTION1.0 を 1 にしない
JSON_HEX_TAGHTML 安全エスケープscript 出力時

推奨デフォルト

 true, 'data' => $rows]);

連想配列と index 配列の違い

PHP の配列は JSON にエンコードする際、キーが連続した整数かどうかで出力が変わります:

 'taro', 'age' => 30];
echo json_encode($assoc);
// → {"name":"taro","age":30}

// 飛び番の整数キー → JSON Object になる
$mixed = [0 => 'a', 2 => 'b', 5 => 'c'];
echo json_encode($mixed);
// → {"0":"a","2":"b","5":"c"}
//   配列ではなくオブジェクト扱いになるので注意

// 強制的に Object 化
echo json_encode([], JSON_FORCE_OBJECT);    // → {}
echo json_encode([]);                       // → []  (デフォルト)

null / false / int の挙動

エラーハンドリング

getMessage());
    http_response_code(500);
    exit;
}

// よくあるエラー原因
// - UTF-8 でない文字列 (SJIS のままなど)
// - INF / NAN を含む
// - 循環参照 (オブジェクトが自分自身を参照)
// - リソース型を含む (file handle 等)

UTF-8 エンコーディング

JSON はUTF-8 必須です。SJIS / EUC-JP / CP932 のままだと json_encode() は false を返します:

 mb_convert_encoding('山田', 'SJIS', 'UTF-8')];
$json = json_encode($bad);  // → false
echo json_last_error_msg(); // → Malformed UTF-8 characters, possibly incorrectly encoded

// 対処: 先に UTF-8 化
function toUtf8($s) {
    return mb_convert_encoding($s, 'UTF-8', 'auto');
}

function deepUtf8($v) {
    if (is_string($v)) return mb_convert_encoding($v, 'UTF-8', 'auto');
    if (is_array($v))  return array_map('deepUtf8', $v);
    return $v;
}

$json = json_encode(deepUtf8($data), JSON_UNESCAPED_UNICODE);

JSON → 配列 (逆変換)

 'taro', 'tags' => ['a','b']]

// stdClass オブジェクトで受ける (デフォルト)
$obj = json_decode($json);
echo $obj->name;             // taro
echo $obj->tags[0];          // a

// 例外化
try {
    $arr = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    error_log($e->getMessage());
}

// ネストの深さ制限 (第三引数、デフォルト 512)
$arr = json_decode($json, true, 1024);

Laravel での JSON 出力

json($data);

// フラグ指定
return response()->json($data,
    200,
    ['Content-Type' => 'application/json; charset=UTF-8'],
    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
);

// Laravel グローバル設定 (config/app.php に追記)
// 'json' => [
//     'encode_options' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
// ],

// Eloquent モデルの toJson
class User extends Model {
    protected $hidden = ['password'];  // JSON に含めない
    protected $casts = [
        'options' => 'array',           // DB の JSON 列を自動デコード
        'is_admin' => 'boolean',
    ];
}

echo $user->toJson(JSON_UNESCAPED_UNICODE);

// Resource (整形)
class UserResource extends JsonResource {
    public function toArray($req): array {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'created_at' => $this->created_at?->toIso8601String(),
        ];
    }
}
return new UserResource($user);

JsonSerializable インターフェース

独自クラスを json_encode() に渡したときの出力を制御:

 $this->amount,
            'currency' => $this->currency,
            'formatted' => number_format($this->amount) . ' ' . $this->currency,
        ];
    }
}

echo json_encode(new Money(1500));
// → {"amount":1500,"currency":"JPY","formatted":"1,500 JPY"}

FAQ

Q: 日本語が 山田 になってしまう
A: JSON_UNESCAPED_UNICODE フラグを付ければ 山田 のまま出力されます。

Q: HTML/script タグ内に出力するとき XSS が心配
A: JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT< 等を 16 進エスケープし、HTML 内に安全に埋め込めます。

Q: 大きな配列を JSON 化するとメモリ不足になる
A: JsonMachine 等のストリーミング JSON エンコーダ、または chunk して NDJSON 出力を検討。