構文:json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false
// 基本例
json_encode(["name" => "Taro", "age" => 25]);
// {"name":"Taro","age":25}
json_encode(["name" => "太郎"], JSON_UNESCAPED_UNICODE);
// {"name":"太郎"}(日本語をそのまま出力)
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
// インデント付きで整形出力
PHPのjson_encode()は、配列やオブジェクトをJSON形式の文字列に変換する組み込み関数です。API開発やAJAX通信、キャッシュ用のキー生成、DBへのJSON保存など幅広い場面で使われます。ただし日本語が\uXXXX形式にエスケープされる、スラッシュが\/にエスケープされる、変換に失敗するとfalseを返すなど、初見だとつまずきやすい挙動もあります。この記事では基本構文からオプションフラグ、エラー処理、Laravelでの実践的な使い方まで解説します。
json_encode関数とは?
PHPのjson_encode()は、配列・オブジェクト・文字列・数値・真偽値などのPHPの値をJSON形式の文字列に変換する組み込み関数です。JSON文字列をPHPの値に戻すjson_decode()とペアで使われることが多い関数です。
json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false
引数の詳細
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
$value |
mixed | 必須 | — | エンコードする値。resource型以外の任意の型を指定可能。文字列はUTF-8である必要がある |
$flags |
int | 任意 | 0 |
出力を制御するビットマスク。JSON_PRETTY_PRINTなどを|で組み合わせて指定 |
$depth |
int | 任意 | 512 |
ネストの最大深度。1未満を指定するとPHP 8.0以降はValueError |
⚠️ エンコード対象の文字列は必ずUTF-8である必要があります。Shift_JISやEUC-JPが混入していると変換に失敗しfalseが返ります。また戻り値は成功時string、失敗時falseなので、if ($json)のような真偽値判定ではなくif ($json === false)で厳密にチェックしてください(空文字列""や"0"もfalsyになるため)。
基本的な使い方
連想配列を渡すとJSONオブジェクト、添字配列を渡すとJSON配列に変換されます。
$array = [
"name" => "Taro",
"email" => "taro@example.com",
"age" => 25,
];
$json = json_encode($array);
echo $json;
// {"name":"Taro","email":"taro@example.com","age":25}
添字配列はJSON配列になる
$list = ["php", "laravel", "json"];
echo json_encode($list);
// ["php","laravel","json"]
オブジェクトをエンコードする
public プロパティを持つオブジェクトもそのままエンコードできます。
class Product
{
public string $name = "Tシャツ";
public int $price = 2980;
}
echo json_encode(new Product());
// {"name":"Tシャツ","price":2980}
ネストした配列・オブジェクトの変換
$data = [
"user" => [
"name" => "Taro",
"address" => [
"city" => "Tokyo",
"zip" => "100-0001",
],
],
"tags" => ["php", "json", "laravel"],
];
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
/*
{
"user": {
"name": "Taro",
"address": {
"city": "Tokyo",
"zip": "100-0001"
}
},
"tags": ["php", "json", "laravel"]
}
*/
出力を制御するフラグ(オプション)
第2引数の$flagsには複数のフラグを|(ビットOR)で組み合わせて指定できます。特によく使うのは次の3つです。
JSON_PRETTY_PRINT — 整形して出力する
$json = json_encode(["name" => "Taro", "age" => 25], JSON_PRETTY_PRINT);
echo $json;
/*
{
"name": "Taro",
"age": 25
}
*/
JSON_UNESCAPED_UNICODE — 日本語が\uXXXXになるのを防ぐ
デフォルトでは日本語などのマルチバイト文字が\uXXXX形式のエスケープシーケンスに変換されます。JSON仕様としては正しい表現ですが、ログやレスポンスをそのまま目視確認したい場合は読みにくくなります。
echo json_encode(["name" => "太郎"]);
// {"name":"太郎"}
echo json_encode(["name" => "太郎"], JSON_UNESCAPED_UNICODE);
// {"name":"太郎"}
JSON_UNESCAPED_SLASHES — URLの/がエスケープされるのを防ぐ
echo json_encode(["url" => "https://example.com/path"]);
// {"url":"https:\/\/example.com\/path"}
echo json_encode(["url" => "https://example.com/path"], JSON_UNESCAPED_SLASHES);
// {"url":"https://example.com/path"}
フラグを組み合わせる
APIレスポンスやログ出力では、この3つを組み合わせるのが定番です。
$json = json_encode(
["url" => "https://example.com", "name" => "田中"],
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
);
その他の主なフラグ
| フラグ | 対応バージョン | 説明 |
|---|---|---|
JSON_NUMERIC_CHECK |
— | 数値形式の文字列を数値としてエンコードする |
JSON_FORCE_OBJECT |
— | 配列でも常にJSONオブジェクト({})として出力する |
JSON_PRESERVE_ZERO_FRACTION |
PHP 5.6.6+ | 12.0のような小数を12ではなく12.0のまま出力する |
JSON_PARTIAL_OUTPUT_ON_ERROR |
PHP 5.5.0+ | 変換不可な値をエンコードできない箇所だけ0にして、失敗せず部分的に出力する |
JSON_HEX_TAG / JSON_HEX_AMP / JSON_HEX_APOS / JSON_HEX_QUOT |
— | < > & ' "をそれぞれ\uXXXXにエスケープする(HTML内に直接埋め込む場合向け) |
JSON_INVALID_UTF8_IGNORE / JSON_INVALID_UTF8_SUBSTITUTE |
PHP 7.2.0+ | 不正なUTF-8バイト列を無視、または代替文字に置換して失敗させない |
JSON_UNESCAPED_LINE_TERMINATORS |
PHP 7.1.0+ | U+2028・U+2029(行区切り文字)をエスケープしない |
JSON_THROW_ON_ERROR |
PHP 7.3.0+ | 失敗時にfalseではなくJsonExceptionをスローする |
エラー処理(falseになるケース)
json_encode()は変換に失敗するとfalseを返します。原因を調べるにはjson_last_error()/json_last_error_msg()を使います。
$result = json_encode($value);
if ($result === false) {
echo "JSONエンコードエラー: " . json_last_error_msg();
}
主なエラーコード
| 定数 | 値 | 内容 |
|---|---|---|
JSON_ERROR_NONE |
0 | エラーなし |
JSON_ERROR_DEPTH |
1 | 最大スタック深さを超えた |
JSON_ERROR_UTF8 |
5 | UTF-8として不正な文字が含まれる |
JSON_ERROR_RECURSION |
6 | 循環参照しているオブジェクト/配列が含まれる |
JSON_ERROR_INF_OR_NAN |
7 | NANやINFなど無限大・非数の値が含まれる |
JSON_ERROR_UNSUPPORTED_TYPE |
8 | resource型などエンコード不可能な型が含まれる |
JSON_THROW_ON_ERROR を使う
PHP 7.3以降ではJSON_THROW_ON_ERRORフラグを指定すると、失敗時にfalseではなく例外(JsonException)がスローされます。json_last_error()を都度チェックする必要がなくなり、うっかりチェックを忘れてfalseのまま処理が進む事故も防げます。
try {
$json = json_encode($resource, JSON_THROW_ON_ERROR); // resource型はエンコード不可
} catch (\JsonException $e) {
echo "JSONエンコード失敗: " . $e->getMessage();
// Type is not supported
}
よくある落とし穴・注意点
オブジェクトのprivate/protectedプロパティは出力されない
json_encode()はオブジェクトのpublicプロパティのみを対象にします。private/protectedなプロパティを含めたい、またはカスタムの変換ロジックを適用したい場合はJsonSerializableインターフェースを実装します。
class Money implements \JsonSerializable
{
public function __construct(
private int $amount,
private string $currency = "JPY"
) {}
public function jsonSerialize(): mixed
{
return [
"amount" => $this->amount,
"currency" => $this->currency,
];
}
}
echo json_encode(new Money(1000));
// {"amount":1000,"currency":"JPY"}
空配列は[]になる({}にしたい場合はJSON_FORCE_OBJECT)
PHPの空配列[]は連想配列か添字配列か区別できないため、デフォルトではJSON配列[]として出力されます。API仕様上、空でも必ずJSONオブジェクト{}として返したい場合はJSON_FORCE_OBJECTを使うか、(object) []にキャストします。
echo json_encode([]); // []
echo json_encode([], JSON_FORCE_OBJECT); // {}
echo json_encode((object) []); // {}
大きな整数は環境によって精度が変わる
PHPのint型の範囲を超える整数は、32ビット環境や範囲外の値では浮動小数点数に変換され、末尾の桁が丸められることがあります。外部APIのID値など精度を保ちたい場合は、あらかじめ文字列として扱うのが安全です。
$id = "12345678901234567890"; // 文字列として保持
echo json_encode(["id" => $id]);
// {"id":"12345678901234567890"}(文字列のまま精度を保持できる)
浮動小数点の末尾.0が消える
12.0のような小数はデフォルトで12として出力されます。小数であることを維持したい場合はJSON_PRESERVE_ZERO_FRACTIONを指定します。
echo json_encode(["price" => 12.0]);
// {"price":12}
echo json_encode(["price" => 12.0], JSON_PRESERVE_ZERO_FRACTION);
// {"price":12.0}
json_encode / json_decode / serialize の使い分け
| 関数 | 役割 | 他言語との互換性 | 主な用途 |
|---|---|---|---|
json_encode() |
PHPの値 → JSON文字列 | あり(言語非依存の標準フォーマット) | API出力、外部連携、可読性が必要なキャッシュ・ログ |
json_decode() |
JSON文字列 → PHPの値 | あり | 外部APIレスポンスの取り込み、JSONファイルの読み込み |
serialize() / unserialize() |
PHPの値 ⇔ PHP固有形式の文字列 | なし(PHP専用) | PHP内部でのキャッシュ、セッション保存など他言語と連携しない用途 |
他言語のシステムやフロントエンドと値をやり取りする場合はjson_encode/json_decodeを、PHPのプロセス内だけで完結するデータ保存にはserialize/unserializeを使うのが基本方針です。
Laravelでjson_encodeを使う/避ける場面
Laravelではjson_encode()を直接呼ばなくても、フレームワークが内部で同等の処理を行ってくれる場面が多くあります。
APIレスポンスにはresponse()->json()
public function index()
{
$users = User::all();
return response()->json([
"data" => $users,
"count" => $users->count(),
]);
// 内部で toArray() → json_encode が行われ、Content-Type ヘッダーも自動付与される
}
EloquentモデルはtoJson()でJSON文字列に変換できる
$user = User::find(1);
$json = $user->toJson();
// json_encode($user->toArray()) とほぼ同等
$json = $user->toJson(JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
// json_encodeと同じフラグをそのまま渡せる
DBにJSONカラムとして保存するならEloquent cast
class User extends Model
{
protected $casts = [
"settings" => "array", // 保存時に自動でjson_encode、取得時に自動でjson_decode
];
}
$user->settings = ["theme" => "dark", "lang" => "ja"];
$user->save(); // 手動でjson_encodeを呼ぶ必要がない
それでもjson_encodeを直接使う場面
Laravelを使っていても、次のような場合はjson_encode()を直接呼びます。
- キャッシュキーの生成(パラメータ配列をハッシュ化する下準備として)
- Bladeテンプレート内でJavaScriptにPHPの値をそのまま渡したいとき(
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG)のようにHTML埋め込み向けフラグと併用) - Eloquentモデルを介さない、単純な配列やDTOをJSON文字列化したいとき
<script>
const config = <?= json_encode($config, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG) ?>;
</script>
関連記事
- PHPのjson_decodeの使い方とnullになる原因|配列変換・エラー処理をサンプルコード付きで解説 — JSON文字列をPHPの値に戻す逆方向の変換はこちら
- PHP 連想配列の使い方|作成・取得・追加・削除からforeach・関数まで — エンコード対象の連想配列を組み立てる基礎はこちら
- md5 — 文字列のMD5ハッシュを計算 — json_encodeの結果をキャッシュキーに使う実例はこちら
FAQ
json_encodeで日本語が文字化けする/\uXXXXになるのはなぜ?
文字化けではなく、JSON仕様に沿った正しいエスケープ表現です。人間が読める形式でそのまま出力したい場合はJSON_UNESCAPED_UNICODEフラグを指定してください。
echo json_encode(["name" => "太郎"], JSON_UNESCAPED_UNICODE);
// {"name":"太郎"}
json_encodeがfalseを返すのはどんなとき?
循環参照しているオブジェクト、resource型の値、NAN/INFなどのfloat、深さ上限を超えたネスト、不正なUTF-8文字列を含む場合などです。json_last_error_msg()で具体的な原因を確認できます。
連想配列とオブジェクトどちらでも同じ結果になる?
キーと値の構造が同じであれば、連想配列とpublicプロパティのみのオブジェクトは同じJSON文字列になります。ただしオブジェクトの場合、private/protectedプロパティは出力されない点に注意してください。
スラッシュ(/)がエスケープされるのを防ぐには?
JSON_UNESCAPED_SLASHESフラグを指定します。URLを含むデータをエンコードする際によく使います。
echo json_encode(["url" => "https://example.com"], JSON_UNESCAPED_SLASHES);
// {"url":"https://example.com"}
LaravelでEloquentモデルをそのままJSON文字列にするには?
$model->toJson()を使います。json_encode()と同じフラグを引数に渡せます。API出力であればresponse()->json($model)を使うほうが、ステータスコードやヘッダーの制御も含めて簡潔です。
まとめ
json_encode()関数のポイントをまとめます。
json_encode($value, $flags, $depth)でPHPの配列/オブジェクトをJSON文字列に変換する- 日本語をそのまま出力したいなら
JSON_UNESCAPED_UNICODE、URLの/を残したいならJSON_UNESCAPED_SLASHES、整形出力にはJSON_PRETTY_PRINTを使う - 失敗時は
falseを返す。=== falseで厳密にチェックするか、JSON_THROW_ON_ERRORで例外に切り替える - オブジェクトはpublicプロパティのみが対象。柔軟に制御したい場合は
JsonSerializableを実装する - Laravelでは
response()->json()、$model->toJson()、Eloquentの$castsを使うと、多くの場面でjson_encodeを直接呼ぶ必要がなくなる
基本形のjson_encode($array)から始め、日本語やURLを扱うときはエスケープ系のフラグを、失敗が許容できない処理ではJSON_THROW_ON_ERRORを組み合わせることで、意図しない出力やエラーの見落としを防げます。

コメント