PHP: настройка заголовка Content-Type для JSON данных

Раздел: Веб-разработка -> HTTP запросы

Основные методы установки заголовка Content-Type application/json

Как в PHP наиболее правильно установить заголовок Content-Type для JSON ответа?

Основной способ - использовать функцию header() перед выводом данных. Это гарантирует, что HTTP-ответ будет содержать правильный MIME-тип. Пример кода:

<?php
header('Content-Type: application/json');
$data = ['status' => 'ok', 'message' => 'Данные получены'];
echo json_encode($data, JSON_UNESCAPED_UNICODE);
?>

Php get (обработка get запросов в php)

Важно: вызов header() должен быть выполнен до любого вывода (включая пробелы или HTML). Иначе PHP выдаст предупреждение и заголовок не будет установлен.

Распространенная проблема - "headers already sent". Причины: пробелы перед <?php, echo, включение файлов с выводом. Решение: проверить файлы на наличие лишних символов, использовать буферизацию вывода.

Пример проверки с помощью headers_sent():

if (!headers_sent()) {
    header('Content-Type: application/json');
} else {
    // логирование ошибки
}

Php file http (работа с файлами по http в php)

Как установить заголовок с заменой или добавлением?

Функция header принимает второй параметр replace (по умолчанию true). Если установить false, заголовок будет добавлен, что может привести к множественным значениям Content-Type. Обычно требуется замена. Пример:

header('Content-Type: application/json', true); // явная замена

Http content php (отправка контента по http в php)

Проблема: если в коде уже есть вызов header с другим Content-Type, повторный вызов с replace=true перезапишет его. Если нужно сохранить оба, используйте replace=false, но это редкость.

Как использовать буферизацию для гарантированной отправки заголовков?

При активной буферизации вывода можно вызвать header в любом месте скрипта. Пример с ob_start():

<?php
ob_start();
// произвольный код, который может выводить текст
echo "Текст до заголовка"; // это попадет в буфер
header('Content-Type: application/json');
ob_clean(); // очищаем буфер, чтобы не выводить "Текст до заголовка"
echo json_encode($data);
ob_end_flush();
?>

Php https post (отправка https post запросов в php)

Этот подход позволяет избежать ошибок, если вывод происходит раньше.

Ошибка: забыть вызвать ob_end_flush() или ob_clean() в нужном порядке. Решение: тщательно продумывать логику буферизации.

Как установить Content-Type с указанием кодировки?

Часто требуется указать charset, например UTF-8. Это делается добавлением параметра:

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

Php post json (php: отправка post-запроса с json)

Такой заголовок сообщает клиенту, что данные закодированы в UTF-8, что важно для корректного отображения юникода.

Проблема: если данные содержат символы не в UTF-8, клиент может интерпретировать их неверно. Решение: всегда кодировать JSON с флагом JSON_UNESCAPED_UNICODE и хранить данные в UTF-8.

Как установить заголовок через ini-настройки или серверные директивы?

Можно задать заголовок по умолчанию в .htaccess (Apache) или через PHP-инструкцию default_mimetype в php.ini. Однако это глобальное изменение, влияющее на все ответы. Пример для Apache:

Header set Content-Type "application/json"

Но такой подход негибкий, так как один сайт может отдавать разные типы данных. Рекомендуется устанавливать заголовок в коде.

Проблема: при использовании серверных директив можно случайно переопределить заголовки для статических файлов. Решение: применять директивы только для определённых расширений или директорий.

- Php get request (get запрос в php)
- Php post request (post запрос в php)
- Home php id index (передача параметра id в home.php)

Расширенные примеры использования Content-Type application/json

Пример 1: Полный скрипт API с обработкой ошибок и заголовками

Скрипт проверяет метод запроса, устанавливает заголовки CORS и Content-Type, обрабатывает ошибки и возвращает JSON.

Пример
<?php
// Устанавливаем заголовки
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
// Обработка preflight запроса
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}
try {
    // Проверка метода
    if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
        throw new Exception('Метод не поддерживается', 405);
    }
    // Основная логика
    $data = ['name' => 'John', 'age' => 30];
    echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
} catch (Exception $e) {
    http_response_code($e->getCode() ?: 500);
    echo json_encode(['error' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
?>

Результат (HTTP-заголовки и тело ответа):

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS

{
    "name": "John",
    "age": 30
}

Пример 2: Проверка отправленных заголовков с помощью headers_list()

Иногда полезно убедиться, что заголовок установлен корректно. Функция headers_list() возвращает массив всех заголовков, которые будут отправлены.

Пример
<?php
header('Content-Type: application/json');
$data = ['foo' => 'bar'];
echo json_encode($data);
// Проверим заголовки (до вывода, но после header)
$headers = headers_list();
print_r($headers);
?>

Результат (в теле ответа после JSON):

{"foo":"bar"}Array
(
    [0] => Content-Type: application/json
    [1] => X-Powered-By: PHP/8.2
)

Обратите внимание: заголовок уже отправлен, но print_r выводится в теле. Этот пример иллюстрирует, что headers_list() работает только до отправки заголовков. В реальном API не следует смешивать вывод JSON и отладочную информацию.

Пример 3: Использование json_encode с различными флагами

Для корректной работы JSON с юникодом и форматированием используются флаги:

Пример
<?php
header('Content-Type: application/json; charset=utf-8');
$data = ['city' => 'Санкт-Петербург', 'temp' => -5.5];
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
?>

Результат:

{
    "city": "Санкт-Петербург",
    "temp": -5.5
}

Пример 4: Отправка JSON из файла или через stream

Если JSON уже сохранён в файле, можно отправить его с правильным заголовком, не используя json_encode:

Пример
<?php
header('Content-Type: application/json');
readfile('/path/to/data.json');
exit;
?>

Этот способ эффективен для статических JSON-файлов.

Пример 5: Динамическое определение Content-Type на основе Accept заголовка

Сервер может анализировать заголовок Accept от клиента и устанавливать Content-Type соответственно. Пример для поддержки JSON и XML:

Пример
<?php
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
if (strpos($accept, 'application/json') !== false) {
    header('Content-Type: application/json');
    echo json_encode(['format' => 'json']);
} elseif (strpos($accept, 'text/xml') !== false) {
    header('Content-Type: text/xml');
    echo '<response><format>xml</format></response>';
} else {
    header('Content-Type: text/plain');
    echo 'Default format';
}
?>

Такой подход используется в REST API для контент-негосиации.

PHP: установка Content-Type: application/json - comments

En
Php content json (php)