Avatar ·

Как правильно вернуть JSON из PHP скрипта и почему у меня ничего не работает?

Всем привет! Я новичок в PHP, пишу простое API для тестового проекта. Нужно, чтобы скрипт возвращал данные в формате JSON. Я написал такой код: ```php "Иван", "age" => 25, "city" => "Москва"); echo json_encode($data); ?> ``` Но когда я вызываю этот скрипт через fetch() в JavaScript или просто через curl, я получаю странные результаты. В браузере вижу просто текст на странице, а JavaScript говорит, что ответ не является валидным JSON. Иногда вообще приходит пустой ответ. Я пробовал читать документацию, но там много непонятных терминов про заголовки, MIME-типы и что-то про буферизацию вывода. Может быть, нужно что-то ещё сделать, кроме вызова json_encode()? Я слышал, что нужно устанавливать какой-то Content-Type, но не понимаю зачем и как. Подскажите, пожалуйста, как правильно организовать возврат JSON из PHP, чтобы клиент (браузер, curl, мобильное приложение) мог его корректно принять и обработать. Приведите рабочий пример с объяснением. Спасибо! <<>>

Правильный способ возврата JSON из PHP

Проблема в том, что вы вызываете json_encode() и просто выводите результат через echo. Этого недостаточно для корректной работы с JSON. Давайте разберем все шаги по порядку.

1. Установка правильного заголовка Content-Type

HTTP-заголовок Content-Type сообщает клиенту (браузеру, curl, JavaScript), в каком формате сервер отправляет данные. Для JSON используется MIME-тип application/json. Если этого не сделать, клиент может интерпретировать ответ как обычный текст или HTML.

<?php
$data = [
    "name" => "Иван",
    "age" => 25,
    "city" => "Москва"
];

header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
?>

2. Запрет на случайный вывод до JSON

Очень частая ошибка — пробелы, пустые строки или лишние символы до открывающего тега <?php или после закрывающего ?>. Любой символ, попавший в вывод до вызова json_encode(), сделает JSON невалидным.

Плохо:

[пробел]
<?php
echo json_encode($data);
?>
[пустая строка]

Хорошо:

<?php
header('Content-Type: application/json');
echo json_encode($data);
?>

Лучше вообще не ставить закрывающий тег ?> в файлах, которые содержат только PHP-код — это предотвратит случайный вывод пробелов.

3. Обработка ошибок и кодировка

Функция json_encode() может вернуть false, если данные содержат некорректные символы (например, не-UTF-8). Всегда проверяйте результат!

<?php
header('Content-Type: application/json; charset=utf-8');

$data = [
    "name" => "Иван",
    "age" => 25,
    "message" => "Привет, мир!"
];

$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

if ($json === false) {
    // Обработка ошибки
    http_response_code(500);
    echo json_encode(["error" => "Ошибка кодирования JSON: " . json_last_error_msg()]);
    exit;
}

echo $json;
?>

Флаг JSON_UNESCAPED_UNICODE сохраняет русские буквы как есть (вместо \uXXXX), а JSON_UNESCAPED_SLASHES не экранирует слеши.

4. Полный рабочий пример

<?php
// 1. Устанавливаем заголовок
header('Content-Type: application/json; charset=utf-8');

// 2. Данные для отправки
$response = [
    "status" => "success",
    "data" => [
        "id" => 1,
        "name" => "Иван",
        "age" => 25,
        "skills" => ["PHP", "JavaScript", "Python"]
    ],
    "timestamp" => time()
];

// 3. Кодируем с проверкой
$json = json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
if ($json === false) {
    http_response_code(500);
    echo json_encode(["error" => "Internal server error"]);
    exit;
}

// 4. Отдаем результат
echo $json;
?>

5. Проверка через curl

После правильной настройки ваш скрипт можно протестировать в терминале:

curl -i http://your-site.com/api.php

Вы должны увидеть заголовок Content-Type: application/json и корректный JSON в теле ответа.

Ключевые моменты:

  • Всегда устанавливайте заголовок Content-Type: application/json перед выводом данных.
  • Убедитесь, что в файле нет лишних символов до <?php и после ?>.
  • Используйте флаги JSON_UNESCAPED_UNICODE и JSON_UNESCAPED_SLASHES для корректной работы с кириллицей.
  • Проверяйте результат json_encode() на false.
  • Не используйте закрывающий тег ?> в файлах с чистым PHP-кодом.
<<>>

Альтернативный подход: использование PHP-фреймворков

Если вы работаете над серьезным проектом или API, рекомендую использовать готовые решения, например, микрофреймворк Slim или полновесный Laravel. Они автоматически управляют заголовками, кодировкой и обработкой ошибок.

Пример с использованием Slim 4:

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->get('/api/user/{id}', function (Request $request, Response $response, array $args) {
    $data = [
        "id" => (int)$args['id'],
        "name" => "Иван",
        "age" => 25
    ];
    
    $payload = json_encode($data, JSON_UNESCAPED_UNICODE);
    $response->getBody()->write($payload);
    
    return $response
        ->withHeader('Content-Type', 'application/json')
        ->withStatus(200);
});

$app->run();

Преимущества такого подхода:

  • Автоматическая обработка заголовков и статусов HTTP
  • Встроенная поддержка CORS, middleware, роутинга
  • Защита от типичных ошибок (случайный вывод, пробелы)
  • Удобное тестирование и документация

Если вы только начинаете — сначала освойте чистый PHP, но для продакшена всегда используйте фреймворки. Это сэкономит часы отладки и сделает код профессиональным.