Настройка HTTP заголовков в cURL для PHP

Раздел: Работа с HTTP -> Установка заголовка H в curl

Основной способ установки заголовков в cURL

Для отправки HTTP-запроса с произвольными заголовками в PHP используется функция curl_setopt с параметром CURLOPT_HTTPHEADER. Этот параметр принимает массив строк, каждая строка - это полный заголовок в формате "Имя: значение".

$ch = curl_init('https://api.example.com/data');
$headers = [
    'Content-Type: application/json',
    'Authorization: Bearer mytoken123',
    'X-Custom-Header: myvalue'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

Curl h php (php curl с заголовком h (curl -h))

В данном примере задаются три заголовка. После выполнения запроса переменная $response содержит тело ответа. Обратите внимание, что заголовки добавляются к стандартным заголовкам, отправляемым cURL (например, Host). Если требуется переопределить стандартный заголовок, его можно указать в массиве - cURL отправит ваше значение вместо стандартного.

Типичные ошибки:

  • Забывают указать двоеточие между именем и значением. Например, 'Content-Type application/json' не будет распознан как корректный заголовок.
  • Указывают заголовок с символом переноса строки - это может нарушить структуру HTTP-запроса.
  • Передают пустой массив - это удалит все пользовательские заголовки, но стандартные останутся.

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

Некоторые HTTP-заголовки могут повторяться (например, Set-Cookie в ответе, но в запросе не рекомендуется). В cURL можно передать массив с одинаковыми именами. Однако для некоторых серверов это может быть недопустимо. Пример:

$headers = [
    'X-Custom: value1',
    'X-Custom: value2'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

cURL отправит два заголовка с именем X-Custom. Но если сервер ожидает одно значение, такое поведение может привести к ошибке.

Проблема: не все серверы корректно обрабатывают повторяющиеся заголовки. Лучше комбинировать значения через запятую, если это разрешено спецификацией.

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

Обычно значения заголовков формируются в коде. Например, токен авторизации может храниться в конфигурации:

$token = getenv('API_TOKEN');
$headers = [
    'Authorization: Bearer ' . $token
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Важно экранировать специальные символы, если они могут содержаться в значении. Сама строка заголовка не должна содержать символы новой строки.

Ошибка: если $token содержит перевод строки, cURL может обработать это как завершение заголовка. Рекомендуется проверять и удалять нежелательные символы.

Как задать заголовок Content-Type для отправки JSON или XML?

Один из частых случаев - указание типа контента для POST-запросов:

$data = ['key' => 'value'];
$json = json_encode($data);
$headers = [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($json)
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Если не указать Content-Type, сервер может неверно интерпретировать тело запроса.

Типичная ошибка: забывают перекодировать данные в JSON или не указывают заголовок. В результате сервер получает данные в неправильном формате.

Как убрать стандартные заголовки, например, Host?

cURL автоматически добавляет заголовок Host на основе URL. Если требуется изменить его, достаточно передать свой заголовок Host в массиве:

$headers = [
    'Host: custom.example.com'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Аналогично можно переопределить User-Agent, Accept и другие стандартные заголовки.

Ошибка: если ошибиться в формате, cURL может отправить два заголовка Host - ваш и стандартный. Проверьте, что заголовок корректен.

Как обработать ошибки, связанные с заголовками?

После вызова curl_exec можно проверить ошибки через curl_error. Если заголовки указаны некорректно, cURL может вернуть false или код ошибки. Например:

$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'cURL error: ' . curl_error($ch);
} else {
    // разбор ответа
}

Также можно проверить HTTP-код ответа с помощью curl_getinfo($ch, CURLINFO_HTTP_CODE). Некорректные заголовки часто приводят к ошибке 400 или 500.

Если после добавления заголовков запрос перестал работать, проверьте лог сервера или используйте CURLOPT_VERBOSE для отладки.

Как задать заголовки через командную строку (curl -H) и перенести их в PHP?

В командной строке curl используется флаг -H. Например:

curl -H "Content-Type: application/json" -H "Authorization: Bearer token" https://api.example.com

В PHP нужно преобразовать все заголовки в массив и передать в CURLOPT_HTTPHEADER.

$headers = [
    'Content-Type: application/json',
    'Authorization: Bearer token'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Это полный аналог. Обратите внимание, что в командной строке допускается указывать заголовки с кавычками - в PHP кавычки не нужны внутри строки.

Часто путают: в командной строке можно опустить значение после двоеточия (например, -H "X-Custom:"), а в PHP обязательно указывать значение, даже пустое: 'X-Custom: '.

Расширенные примеры работы с заголовками в cURL

Пример 1. Отправка JSON и получение заголовков ответа

Пример
$ch = curl_init('https://jsonplaceholder.typicode.com/posts');
$data = ['title' => 'foo', 'body' => 'bar', 'userId' => 1];
$json = json_encode($data);
$headers = [
    'Content-Type: application/json',
    'Accept: application/json'
];
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $json,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER => true // чтобы получить заголовки ответа
]);
$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$responseHeaders = substr($response, 0, $headerSize);
$responseBody = substr($response, $headerSize);
curl_close($ch);
echo "Ответ сервера:\n";
echo "Заголовки:\n" . $responseHeaders;
echo "Тело:\n" . $responseBody;
Ответ сервера:
Заголовки:
HTTP/2 201
Content-Type: application/json; charset=utf-8
...
Тело:
{
  "id": 101,
  "title": "foo",
  ...
}

Пример 2. Загрузка файла с заголовками

Пример
$filePath = '/path/to/file.txt';
$ch = curl_init('https://upload.example.com/upload');
$postData = [
    'file' => new CURLFile($filePath)
];
$headers = [
    'Authorization: Bearer upload-token',
    'X-Requested-With: XMLHttpRequest'
];
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $postData,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
{"status": "ok", "filename": "file.txt"}

Пример 3. Условные заголовки

Пример
$isAuthenticated = true;
$headers = ['Content-Type: application/json'];
if ($isAuthenticated) {
    $headers[] = 'Authorization: Bearer secret123';
}
// ... остальная настройка curl

Пример 4. Установка cookie через заголовок

Пример
$headers = [
    'Cookie: session_id=abc123; user=test'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// альтернатива: CURLOPT_COOKIE

Пример 5. Переопределение User-Agent

Пример
$headers = [
    'User-Agent: MyCustomBot/1.0'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Пример 6. Отладка с CURLOPT_VERBOSE

Пример
$ch = curl_init('https://api.example.com');
curl_setopt_array($ch, [
    CURLOPT_VERBOSE => true,
    CURLOPT_STDERR => fopen('php://output', 'w'),
    CURLOPT_HTTPHEADER => ['X-Custom: test']
]);
curl_exec($ch);
curl_close($ch);
*   Trying ...
* Connected to ...
> GET / HTTP/1.1
> Host: api.example.com
> Accept: */*
> X-Custom: test
...

Пример 7. Многопоточный cURL с заголовками

Пример
$urls = ['url1', 'url2'];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['X-Source: multi']
    ]);
    curl_multi_add_handle($mh, $ch);
    $handles[] = $ch;
}
$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running > 0);
foreach ($handles as $ch) {
    $response = curl_multi_getcontent($ch);
    echo $response;
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);

PHP curl с заголовком H (curl -H) - comments

En
Curl h php (php)