json_encode
<?php
$user = ["name" => "Ruban", "age" => 30, "admin" => true];
echo json_encode($user);
// {"name":"Ruban","age":30,"admin":true}
// Pretty + unicode-friendly + no escaped slashes
echo json_encode($user,
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// Empty array -> [] (object pass-through preserves stdClass as {})
echo json_encode([]); // "[]"
echo json_encode(new stdClass); // "{}"
// Force an array to be encoded as object
echo json_encode($map, JSON_FORCE_OBJECT);
json_decode
<?php
$json = '{"name":"Ruban","age":30,"tags":["php","web"]}';
// As objects (default)
$obj = json_decode($json);
echo $obj->name; // "Ruban"
echo $obj->tags[0]; // "php"
// As associative array (recommended for most cases)
$arr = json_decode($json, associative: true);
echo $arr["name"];
echo $arr["tags"][0];
// Limit recursion depth
$x = json_decode($json, true, depth: 32);
// Decode large integers as strings (no float precision loss)
$x = json_decode($json, true, flags: JSON_BIGINT_AS_STRING);
Error Handling
<?php
// Modern - throw on error (PHP 7.3+)
try {
$data = json_decode($input, true, flags: JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
http_response_code(400);
echo "Invalid JSON: " . $e->getMessage();
}
// Old-style (still works)
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
die("JSON error: " . json_last_error_msg());
}
JsonSerializable Interface
Control exactly how your object is converted to JSON:
<?php
class User implements JsonSerializable {
public function __construct(
public int $id,
public string $name,
private string $passwordHash, // private - keep it out of JSON
) {}
public function jsonSerialize(): array {
return [
"id" => $this->id,
"name" => $this->name,
// passwordHash deliberately omitted
];
}
}
$user = new User(1, "Ruban", "secret-hash");
echo json_encode($user); // {"id":1,"name":"Ruban"}
Unicode & Escaping
<?php
$data = ["city" => "São Paulo", "url" => "https://example.com/path"];
echo json_encode($data);
// {"city":"São Paulo","url":"https:\/\/example.com\/path"}
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
// {"city":"São Paulo","url":"https://example.com/path"}
// For HTML-safe inline JSON (e.g., in a <script> tag)
echo json_encode($data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT);
Building a JSON API Endpoint
<?php
header("Content-Type: application/json; charset=utf-8");
try {
$method = $_SERVER["REQUEST_METHOD"];
if ($method === "POST") {
$input = json_decode(
file_get_contents("php://input"),
true,
flags: JSON_THROW_ON_ERROR
);
// validate $input ...
$user = createUser($input);
http_response_code(201);
echo json_encode($user);
} elseif ($method === "GET") {
$users = getAllUsers();
echo json_encode([
"data" => $users,
"count" => count($users),
]);
} else {
http_response_code(405);
echo json_encode(["error" => "Method not allowed"]);
}
} catch (JsonException $e) {
http_response_code(400);
echo json_encode(["error" => "Invalid JSON"]);
} catch (Throwable $e) {
error_log($e);
http_response_code(500);
echo json_encode(["error" => "Internal error"]);
}
Consuming a JSON API
<?php
// Simple GET with file_get_contents
$context = stream_context_create([
"http" => ["header" => "Accept: application/json"],
]);
$body = file_get_contents("https://api.example.com/users/42", false, $context);
$user = json_decode($body, true);
// POST with cURL (more control, better for production)
$ch = curl_init("https://api.example.com/users");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(["name" => "Ruban"]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Authorization: Bearer " . $token,
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 200 && $status < 300) {
$created = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
}