How to Read Request Headers in PHP
When typing a URL in the browser’s address bar and trying to access it, an HTTP request is sent to the server by the browser. It encompasses information in a text-record state including the type, the capabilities, user’s operation system, the browser generating the request, and more.
Getting the request header, the web server sends an HTTP response head to the client.
Below, we will show you how to read any request header in PHP.
Using the getallheaders() Function
To achieve what was described above, you can use the getllheaders() function.
Let’s check out an example with its output:
foreach (getallheaders() as $name => $value) < echo "$name: $value
"; > ?>
Host: 127.0.0.3:2025 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36 Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: en-US, en;q=0.9
Using apache_request_headers() Function
Now, let’s check out an example of using another helpful method that is the apache_request_headers() function:
$header = apache_request_headers(); foreach ($header as $headers => $value) < echo "$headers: $value
\n"; > ?>
The output will look as follows:
Host: 127.0.0.6:2027 Connection: keep-alive Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36 Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: en-US, en;q=0.9
Describing HTTP Headers
An HTTP header is considered a code, which transfers the data between the browser and the web server.
Generally, HTTP headers are used for the communication between the client and the server in both of the directions.
getallheaders
This function is an alias for apache_request_headers() . Please read the apache_request_headers() documentation for more information on how this function works.
Parameters
This function has no parameters.
Return Values
An associative array of all the HTTP headers in the current request, or false on failure.
Changelog
Version | Description |
---|---|
7.3.0 | This function became available in the FPM SAPI. |
Examples
Example #1 getallheaders() example
foreach ( getallheaders () as $name => $value ) echo » $name : $value \n» ;
>
See Also
User Contributed Notes 9 notes
it could be useful if you using nginx instead of apache
if (! function_exists ( ‘getallheaders’ ))
<
function getallheaders ()
<
$headers = [];
foreach ( $_SERVER as $name => $value )
<
if ( substr ( $name , 0 , 5 ) == ‘HTTP_’ )
<
$headers [ str_replace ( ‘ ‘ , ‘-‘ , ucwords ( strtolower ( str_replace ( ‘_’ , ‘ ‘ , substr ( $name , 5 )))))] = $value ;
>
>
return $headers ;
>
>
?>
A simple approach to dealing with case insenstive headers (as per RFC2616) is via the built in array_change_key_case() function:
$headers = array_change_key_case(getallheaders(), CASE_LOWER);
There’s a polyfill for this that can be downloaded or installed via composer:
Beware that RFC2616 (HTTP/1.1) defines header fields as case-insensitive entities. Therefore, array keys of getallheaders() should be converted first to lower- or uppercase and processed such.
dont forget to add the content_type and content_lenght if your are uploading file:
function emu_getallheaders () <
foreach ( $_SERVER as $name => $value )
<
if ( substr ( $name , 0 , 5 ) == ‘HTTP_’ )
<
$name = str_replace ( ‘ ‘ , ‘-‘ , ucwords ( strtolower ( str_replace ( ‘_’ , ‘ ‘ , substr ( $name , 5 )))));
$headers [ $name ] = $value ;
> else if ( $name == «CONTENT_TYPE» ) <
$headers [ «Content-Type» ] = $value ;
> else if ( $name == «CONTENT_LENGTH» ) <
$headers [ «Content-Length» ] = $value ;
>
>
return $headers ;
>
?>
chears magno c. heck
apache_request_headers replicement for nginx
if (! function_exists ( ‘apache_request_headers’ )) <
function apache_request_headers () <
foreach( $_SERVER as $key => $value ) <
if ( substr ( $key , 0 , 5 )== «HTTP_» ) <
$key = str_replace ( » » , «-» , ucwords ( strtolower ( str_replace ( «_» , » » , substr ( $key , 5 )))));
$out [ $key ]= $value ;
>else <
$out [ $key ]= $value ;
>
>
return $out ;
>
>
?>
warning, at least on php-fpm 8.2.1 and nginx, getallheaders() will return «Content-Length» and «Content-Type» both containing emptystring, even for requests without any of these 2 headers. you can do something like
retrieve token from header:
function getAuthorizationHeader () $headers = null ;
if (isset( $_SERVER [ ‘Authorization’ ])) $headers = trim ( $_SERVER [ «Authorization» ]);
>
elseif (isset( $_SERVER [ ‘HTTP_AUTHORIZATION’ ])) $headers = trim ( $_SERVER [ «HTTP_AUTHORIZATION» ]);
>
elseif ( function_exists ( ‘apache_request_headers’ )) $requestHeaders = apache_request_headers ();
$requestHeaders = array_combine ( array_map ( ‘ucwords’ , array_keys ( $requestHeaders )), array_values ( $requestHeaders ));
if (isset( $requestHeaders [ ‘Authorization’ ])) $headers = trim ( $requestHeaders [ ‘Authorization’ ]);
>
>
function getBearerToken () $headers = getAuthorizationHeader ();
if (!empty( $headers )) if ( preg_match ( ‘/Bearer\s(\S+)/’ , $headers , $matches )) return $matches [ 1 ];
>
>
Due to the else part.
>else <
$out[$key]=$value;
All server Variables are added to the headers list, and that’s not the desired outcome.
- Apache Functions
- apache_child_terminate
- apache_get_modules
- apache_get_version
- apache_getenv
- apache_lookup_uri
- apache_note
- apache_request_headers
- apache_response_headers
- apache_setenv
- getallheaders
- virtual
Как мне прочитать любой заголовок запроса в PHP?
См. также:
getallheaders() — (PHP >= 5.4)межплатформенная версияПсевдоним apache_request_headers() apache_response_headers() — Получить все заголовки ответов HTTP.
headers_list() — Получить список заголовков для отправки.Я предполагаю, что это только при использовании сервера Apache . может потребоваться, чтобы ОП знал об этом 🙂
Мне наплевать на 82% любителей. Я забочусь о профессиональных установках. Никто в здравом уме не попытается запустить сайт с высоким трафиком на mod_php.
@Jacco Да, и я думаю, что это отличная причина для голосования. В любой момент лучший ответ должен быть одобрен, а плохой ответ отрицательным. Это не сайт исторических решений 🙂
@ThomasJensen Учтите, что некоторые могут быть заинтересованы в других или во всех заголовках, а не в ‘HTTP_X_REQUESTED_WITH’; Ответ абсолютно верен, и Жако прямо заявил, что он работает только для Apache; То, что в некоторых сценариях это не лучшее / наиболее эффективное решение, не является основанием для понижения IMO.
@Paranaix A: Я не знаю, что вы имеете в виду, я не критиковал степень ответа, и ваши аргументы именно поэтому я начал свой ответ с ответа на конкретный вопрос, а затем разработал более общие знания и ссылки для получения дополнительной информации , Б: Я все еще не думаю, что вы должны поощрять использование apache_request_headers (). Новички, находящие этот вопрос, начнут использовать его, что является позором IMO, когда существуют лучшие функции.
Хотя в нем говорится, что getallheaders разрешен через FastCGI, как насчет PHP-FPM? Кажется, говорят, что функция не определена
Вы сканируете только верхний регистр HTML, что неверно, в RFC2616 (HTTP / 1.1) говорится, что заголовки нечувствительны к регистру, а не только часть значения, которую вы охватили. Имя заголовка тоже может быть строчным.
getallheaders () не является кроссплатформенной версией apache_request_headers() — это ее псевдоним. Так сказано прямо на связанной странице справочника. Я проверил, и функция не определена на nginx.
PHP преобразует имя заголовка http в верхний регистр и меняет черты на подчеркивания. Если у вас есть заголовок My-Custom-Header, вы должны прочитать $ _SERVER [‘HTTP_MY_CUSTOM_HEADER’];
$_SERVER[‘HTTP_XXXXXX_XXXX’] не работает для всех заголовков. На самом деле это работает только для некоторых из них.
@ BrunoCorrêaZimmermann Привет. Не могли бы вы немного расширить свой комментарий? Я пытаюсь найти решение для чтения ВСЕХ заголовков запросов в PHP, не принимая во внимание тип веб-сервера. Вот почему я тебя спрашиваю. Спасибо!
@JurajPetrik: это, конечно, кажется, но, с одной стороны, я не смог найти его написанным в документах PHP (несмотря на то, что я как-то смутно вспомнил, что где-то читал, но поиск в Google не помог). Не могли бы вы указать на что-то «официальное»?
$_SERVER['HTTP_X_REQUESTED_WITH']
Мета-переменные с именами, начинающимися с HTTP_ , содержат значения, считанные из полей заголовка запроса клиента, если используется протокол HTTP. Имя поля заголовка HTTP преобразуется в верхний регистр, все вхождения — заменены на _ и имеют HTTP_ , чтобы присвоить имя мета-переменной.
Могу ли я с уверенностью ожидать, что любой сервер поместит каждый заголовок в переменную $_SERVER ? Документация PHP по адресу php.net/manual/en/reserved.variables.server.php уклончива в том, что мы можем быть там уверены.
Это не будет (всегда) работать, особенно в PHP-fpm (или cgi). Этот заголовок не всегда доступен из PHP.
Используя это решение, я вижу только некоторые заголовки запроса, и в этом случае я не вижу того, который хочу. Chrome отправляет заголовок cache-control , но я не вижу его нигде в $_SERVER . Я вижу несколько заголовков с префиксом HTTP_ , включая HTTP_ACCEPT и HTTP_UPGRADE_INSECURE_REQUESTS и HTTP_USER_AGENT (среди нескольких других). Но ничего для «контроля кэша» и ничего для «прагмы». Это не зависит от регистра или префикса HTTP_ . Я что-то пропустил?
@EvandelaCruz: leserged.online.fr/phpinfo.php Я вижу это здесь: _SERVER[«HTTP_CACHE_CONTROL»] max-age=0
хммм, спасибо . Это на моем сервере Wamp Dev, и я думаю, что PHP работает как модуль Apache, но я не уверен. Позвольте мне проверить мой ящик с FPM и посмотреть, смогу ли я выяснить, почему я не вижу его здесь на wamp .
@Quassnoi хорошо, неважно. Я использую Chrome, у меня открыты инструменты разработчика f12, и у меня установлен флажок «Отключить кэш». И в этом же окне инструментов разработчика я проверил трижды, что заголовки запросов на кэширование действительно отправляются из браузера. Chrome сообщил, что их отправляли. Но $_SERVER не показывал их. Однако после прочтения вашего ответа я проверил свой phpinfo.php и заголовки действительно были там! Итак, я вернулся к своему сценарию отладки: print_r($_SERVER);die(); и сделал полное обновление (Ctrl + F5) и, конечно же, теперь отображаются заголовки кэширования.
@Quassnoi Так что либо в Chrome есть ошибка / недокументированная функция, либо я начинаю сходить с ума в старости, и я не проверял заголовки запросов трижды и / или у меня не было открытых инструментов разработки. Должен ли я удалить свой оригинальный комментарий, чтобы не оказывать поддержку не тому голосу? Или я должен оставить это здесь для точного исторического ради? В любом случае, спасибо за то, что показали мне свое phpinfo. Я бы сразу же сомневался в тебе . сэкономил мне немного времени, преследуя мой хвост.
@EvandelaCruz: если вы можете надежно воспроизвести его, это будет хороший вопрос. Phpinfo не мой, это первый гугл хит «phpinfo онлайн»
@Quassnoi Похоже, это скорее моя вина. Я думаю, что произошло следующее (это, возможно, упущение пользовательского интерфейса, но я бы не назвал это «ошибкой»): я открыл инструменты dev (f12) и нажал «отключить кэш». Я обновил окно и увидел результаты отладки. Затем я щелкнул правой кнопкой мыши страницу и щелкнул «view-source», что открыло еще одну вкладку с исходным кодом (она лучше отформатирована в представлении исходного кода, поскольку я не переносил вывод в
а массив выводился с переводы строки, а не HTML). Ну, на открывшейся вкладке не было открытых инструментов разработки. И так, по-видимому, он не отправил .
. кэширование заголовков запросов. Итак, $ _SERVER сказал правду, что кажется. Поэтому проблема может заключаться в том, что современные браузеры перезагружают страницу при отображении представления исходного кода (хотя и для этого есть причины) или что Chrome должен был поддерживать состояние dev-tools при отображении представления исходного кода. В любом случае, я думаю, что теперь я не в теме, но я хотел предложить заключение.
Это намного понятнее для меня, чем объяснение, принятое OP (даже если решение такое же), и плюс, у него есть пример, это должен быть принятый ответ.