Question
I want to return JSON from a PHP script.
Should I simply echo the result of json_encode()? Do I also need to set the Content-Type header when sending JSON from PHP?
Short Answer
By the end of this page, you will understand how to send JSON responses from PHP correctly, why json_encode() is used, when to echo the output, and why setting the Content-Type: application/json header is important. You will also see common patterns used in APIs and AJAX endpoints.
Concept
JSON is a text format used to send structured data between systems. In PHP, you usually create an array or object, convert it to JSON with json_encode(), and send that JSON text as the response body.
A correct JSON response usually has two parts:
- The body, which contains the JSON string
- The HTTP headers, which tell the client what kind of data is being returned
In PHP, echo sends the response body. So yes, in most cases you do echo json_encode($data);.
You should also usually set the content type header:
header('Content-Type: application/json');
This matters because browsers, JavaScript clients, mobile apps, and API consumers use headers to understand how to parse the response. If you skip the header, the JSON may still appear in the browser, but the client is not being told clearly that the response is JSON.
A common complete pattern looks like this:
header('Content-Type: application/json');
echo json_encode($data);
This concept matters in real programming because JSON is the standard format for:
- REST APIs
- AJAX requests
- Frontend-to-backend communication
- Returning status messages from server-side scripts
- Sending data to mobile or third-party clients
Mental Model
Think of an HTTP response like a package:
- The header is the label on the outside of the package
- The body is the actual content inside
If you send JSON from PHP:
header('Content-Type: application/json')is the label saying "this package contains JSON"echo json_encode($data)is putting the actual JSON into the package
If you only send the body without the label, some clients may still figure it out, but it is less clear and less reliable.
Syntax and Examples
Basic syntax
$data = ['name' => 'Alice', 'age' => 25];
header('Content-Type: application/json');
echo json_encode($data);
What this does
$datais a PHP arrayjson_encode($data)converts it into a JSON stringheader(...)tells the client the response is JSONechosends the JSON to the browser or API client
Example output
{"name":"Alice","age":25}
Example with HTTP status code
$data = ['error' => 'User not found'];
http_response_code(404);
header('Content-Type: application/json');
echo json_encode($data);
This is useful in APIs where the response should include both:
- a proper status code like
404 - a JSON body describing the error
Example with pretty printing for debugging
$data = [
'success' => true,
'items' => ['apple', 'banana', 'orange']
];
header('Content-Type: application/json');
echo json_encode($data, JSON_PRETTY_PRINT);
This makes the JSON easier to read during development.
Step by Step Execution
Consider this PHP code:
<?php
$user = [
'id' => 1,
'name' => 'Sam'
];
header('Content-Type: application/json');
echo json_encode($user);
Step-by-step
-
PHP creates the
$userarray:idis1nameisSam
-
header('Content-Type: application/json');adds an HTTP response header.- This tells the client that the response body should be treated as JSON.
-
json_encode($user)converts the PHP array into a JSON string:
{"id":1,"name":"Sam"}
-
echosends that JSON string as the response body. -
The client receives:
- a
Content-Typeheader ofapplication/json - a body containing valid JSON
- a
Important timing rule
Headers must be sent before output. This will cause problems:
<?php
echo 'Hello';
header('Content-Type: application/json');
Once output has started, PHP may no longer be able to change headers.
Real World Use Cases
AJAX endpoints
A frontend JavaScript app might call a PHP script and expect JSON:
header('Content-Type: application/json');
echo json_encode(['success' => true]);
REST API responses
A PHP API often returns JSON for resources such as users, orders, or products.
header('Content-Type: application/json');
echo json_encode([
'id' => 42,
'email' => 'user@example.com'
]);
Form validation responses
Instead of reloading a page, a backend can return validation errors as JSON:
header('Content-Type: application/json');
echo json_encode([
'success' => false,
'errors' => ['Email is required']
]);
Background tools and integrations
Webhook handlers or internal services often return JSON status messages so other systems can process the result automatically.
Real Codebase Usage
In real projects, developers usually do more than just echo json_encode(...).
Common pattern: structured API response
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'data' => [
'id' => 1,
'name' => 'Alice'
]
]);
This gives responses a predictable structure.
Validation with early return
header('Content-Type: application/json');
if (empty($_GET['id'])) {
http_response_code(400);
echo json_encode(['error' => 'Missing id']);
exit;
}
This is a guard clause: stop early when input is invalid.
Error handling
header('Content-Type: application/json');
try {
$data = ['message' => 'OK'];
echo json_encode($data, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
http_response_code(500);
echo json_encode(['error' => 'JSON encoding failed']);
}
In production code, developers often handle encoding failures explicitly.
Consistent helper function
In larger codebases, teams often create a reusable response function:
function jsonResponse($data, int $statusCode = 200): void {
http_response_code($statusCode);
header('Content-Type: application/json');
echo json_encode($data);
exit;
}
This avoids repeating the same logic everywhere.
Common Mistakes
1. Forgetting json_encode()
Broken code:
$data = ['name' => 'Alice'];
echo $data;
Why it fails:
- PHP arrays cannot be printed as JSON automatically
- You must convert them first
Correct code:
$data = ['name' => 'Alice'];
header('Content-Type: application/json');
echo json_encode($data);
2. Not setting the content type
echo json_encode(['ok' => true]);
This may still output JSON text, but the client is not explicitly told that it is JSON.
Better:
header('Content-Type: application/json');
echo json_encode(['ok' => true]);
3. Sending output before headers
Broken code:
echo 'Starting...';
header('Content-Type: application/json');
echo json_encode(['ok' => true]);
Why it fails:
- Headers should be sent before normal output
- You may get a "headers already sent" warning
4. Mixing plain text and JSON
Broken code:
header('Content-Type: application/json');
echo 'Result: ';
echo json_encode(['ok' => true]);
Why it fails:
- The response is no longer valid JSON
- Clients expecting pure JSON may break
5. Ignoring encoding errors
Some values cannot be encoded properly. You can detect this:
$json = json_encode($data);
if ($json === false) {
echo json_last_error_msg();
}
Or use:
json_encode($data, JSON_THROW_ON_ERROR);
6. Forgetting to stop execution
Sometimes extra HTML or text gets added after JSON output.
header('Content-Type: application/json');
echo json_encode(['ok' => true]);
exit;
Using exit is often helpful in endpoint scripts.
Comparisons
| Approach | What it does | When to use it | Notes |
|---|---|---|---|
echo json_encode($data) | Sends JSON text in the response body | Always when returning JSON | Core output step |
header('Content-Type: application/json') | Tells the client the body is JSON | Usually always | Best practice for APIs and AJAX |
print_r($data) | Prints a human-readable PHP structure | Debugging only | Not valid JSON |
var_dump($data) | Shows type and structure details | Debugging only | Not valid JSON |
json_encode($data, JSON_PRETTY_PRINT) | Outputs formatted JSON | Development or debugging | Larger response size |
http_response_code(404) | Sets the HTTP status code | Error or special responses | Often used with JSON body |
print_r() vs json_encode()
$data = ['name' => 'Alice'];
print_r($data) output:
Array
(
[name] => Alice
)
json_encode($data) output:
{"name":"Alice"}
Only the second one is valid JSON.
With header vs without header
- Without header: the client receives JSON text, but the type may be unclear
- With header: the client clearly knows it is JSON
For modern web development, setting the header is the correct approach.
Cheat Sheet
header('Content-Type: application/json');
echo json_encode($data);
Rules
- Use
json_encode()to convert PHP data to JSON - Use
echoto send the JSON response body - Set
Content-Type: application/jsonbefore output - Set HTTP status codes with
http_response_code()when needed - Avoid mixing JSON with plain text or HTML
- Consider
exit;after output in endpoint scripts
Useful patterns
Success response
header('Content-Type: application/json');
echo json_encode(['success' => true]);
Error response
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['error' => 'Bad request']);
Safer encoding
echo json_encode($data, JSON_THROW_ON_ERROR);
Common errors
echo $array;-> not valid JSON- output before
header(...)-> headers already sent - extra text before/after JSON -> invalid response
- forgetting content type -> unclear response format
FAQ
Do I need to use echo to return JSON in PHP?
Yes. json_encode() creates a JSON string, and echo sends that string in the response body.
Do I need to set the Content-Type header for JSON in PHP?
Yes, usually. Use header('Content-Type: application/json'); so clients know the response is JSON.
Can I return a PHP array directly as JSON?
No. You must convert it using json_encode() first.
What happens if I forget the JSON header?
The response may still contain JSON text, but the client is not clearly told how to interpret it.
Should I call exit after echoing JSON?
Often yes, especially in standalone endpoint scripts. It prevents accidental extra output.
How do I send a JSON error response in PHP?
Set an HTTP status code and return a JSON object:
http_response_code(404);
header('Content-Type: application/json');
echo json_encode(['error' => 'Not found']);
Is print_r() valid for API responses?
No. It is useful for debugging, but it does not produce valid JSON.
How can I check if json_encode() failed?
You can check for false and inspect json_last_error_msg(), or use JSON_THROW_ON_ERROR.
Mini Project
Description
Build a small PHP endpoint that returns JSON for a simple user lookup. This demonstrates the full pattern of sending structured JSON responses, setting the correct content type, validating input, and using HTTP status codes.
Goal
Create a PHP script that returns a user as JSON when an id is provided, and returns a JSON error message when the input is missing or invalid.
Requirements
- Accept an
idvalue from the query string. - Return a JSON response with the matching user when the
idis valid. - Return a
400JSON error ifidis missing. - Return a
404JSON error if no user matches theid. - Set the response content type to JSON.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.