Como leio qualquer cabeçalho de solicitação em PHP


271

Como devo ler qualquer cabeçalho em PHP?

Por exemplo cabeçalho personalizado: X-Requested-With.

Respostas:


345

IF : você só precisa de um único cabeçalho, em vez de todos os cabeçalhos, o método mais rápido é:

<?php
// Replace XXXXXX_XXXX with the name of the header you need in UPPERCASE (and with '-' replaced by '_')
$headerStringValue = $_SERVER['HTTP_XXXXXX_XXXX'];


ELSE SE : você executa o PHP como um módulo Apache ou, a partir do PHP 5.4, usando o FastCGI (método simples):

apache_request_headers ()

<?php
$headers = apache_request_headers();

foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
}


ELSE: Em qualquer outro caso, você pode usar (implementação da terra do usuário):

<?php
function getRequestHeaders() {
    $headers = array();
    foreach($_SERVER as $key => $value) {
        if (substr($key, 0, 5) <> 'HTTP_') {
            continue;
        }
        $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
        $headers[$header] = $value;
    }
    return $headers;
}

$headers = getRequestHeaders();

foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
}


Consulte também :
getallheaders () - (PHP> = 5.4) edição entre plataformas Alias ​​de apache_request_headers() apache_response_headers () - Busque todos os cabeçalhos de resposta HTTP.
headers_list () - Busca uma lista de cabeçalhos a serem enviados.


3
Eu suponho que este é somente quando estiver usando o servidor Apache ... talvez seja necessário deixar o know OP que :)
alex

12
Eu não ligo para 82% dos amadores. Eu me preocupo com instalações profissionais. Ninguém no estado de espírito correto tentaria executar um site de alto tráfego no mod_php.
vartec

11
@Jacco Sim, e acho que isso faz um motivo perfeito para a votação decrescente. A qualquer momento, a melhor resposta deve ser votada e respostas ruins votadas. Este não é um site de soluções históricas :-)
Thomas Jensen

3
@ThomasJensen Considere, porém, que alguns podem estar interessados ​​em outros ou em todos os cabeçalhos e não especialmente em 'HTTP_X_REQUESTED_WITH'; O respondere está absolutamente correto e Jacco declarou explicitamente que só funciona para o apache; O fato de, em alguns cenários, não ser a melhor / mais eficiente solução, não é motivo para uma OMI com voto negativo.
Sebastian Hoffmann

1
@Paranaix R: Não sei o que você quer dizer, não critiquei a extensão da resposta e seu raciocínio é exatamente por isso que iniciei minha resposta respondendo a uma pergunta específica e depois elaborei com conhecimentos e links mais gerais para obter mais informações . B: Ainda acho que você não deve incentivar o uso de apache_request_headers (). Os novatos que encontrarem essa pergunta começarão a usá-la, o que é uma vergonha da IMO, quando existem melhores funções.
9139 Thomas Jensen

371
$_SERVER['HTTP_X_REQUESTED_WITH']

RFC3875 , 4.1.18:

Meta-variáveis ​​com nomes começando com HTTP_contêm valores lidos nos campos de cabeçalho da solicitação do cliente, se o protocolo usado for HTTP. O nome do campo do cabeçalho HTTP é convertido para maiúsculas, possui todas as ocorrências -substituídas _e foi HTTP_anexado para fornecer o nome da metavariável.


6
Posso esperar com segurança que algum servidor coloque todos os cabeçalhos na $_SERVERvariável? A documentação do PHP em php.net/manual/en/reserved.variables.server.php é evasiva sobre o que podemos ter certeza de que estará lá.
Mark Amery

4
Isso não funcionará (sempre), especialmente em PHP-fpm (ou cgi). Esse cabeçalho nem sempre está disponível no PHP.
Glenn Plas

Usando esta solução, vejo apenas alguns dos cabeçalhos de solicitação e, neste caso, não vejo o que desejo. O Chrome está enviando um cache-controlcabeçalho, mas não o vejo em nenhum lugar $_SERVER. Eu vejo vários cabeçalhos prefixados HTTP_, incluindo "HTTP_ACCEPT" e "HTTP_UPGRADE_INSECURE_REQUESTS" e "HTTP_USER_AGENT" (entre vários outros). Mas nada para "controle de cache" também nada para "pragma". Isso é independente do caso ou HTTP_prefixo. Estou esquecendo de algo?
Evan de la Cruz

@EvandelaCruz: leserged.online.fr/phpinfo.php Eu vejo aqui:_SERVER["HTTP_CACHE_CONTROL"] max-age=0
Quassnoi

hmmm, obrigado ... Este é o meu servidor wamp dev e acho que o PHP está sendo executado como um módulo Apache, mas não tenho certeza. Deixe-me ver na minha caixa de prod com FPM e ver se consigo descobrir por que eu não vê-lo aqui na wamp ...
Evan de la Cruz

48

Você deve encontrar todos os cabeçalhos HTTP na $_SERVERvariável global prefixada com HTTP_maiúsculas e com traços (-) substituídos por sublinhados (_).

Por exemplo, você X-Requested-Withpode ser encontrado em:

$_SERVER['HTTP_X_REQUESTED_WITH']

Pode ser conveniente criar uma matriz associativa a partir da $_SERVERvariável Isso pode ser feito em vários estilos, mas aqui está uma função que gera teclas com camelcased:

$headers = array();
foreach ($_SERVER as $key => $value) {
    if (strpos($key, 'HTTP_') === 0) {
        $headers[str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;
    }
}

Agora basta usar $headers['XRequestedWith']para recuperar o cabeçalho desejado.

Manual do PHP em $_SERVER: http://php.net/manual/en/reserved.variables.server.php


3
A melhor resposta, na minha opinião, é a explicação de Thomas com o resultado final de Quassnoi. Uma matriz associativa geralmente não é o necessário, e não é muito fácil descobrir a solução simples lendo a parseRequestHeaders()função. Se for necessária uma matriz associativa, a função apache da IMO é a melhor opção, pois retorna exatamente os cabeçalhos recebidos em vez de uma versão CamelCase mutilada. (De referir ainda que a partir do PHP 5.4, já não Apache somente é.)
Brilliand

Você teria respondido a esses 2 anos e 11 meses mais rápido, essa resposta teria mais de 200 votos positivos.
precisa saber é o seguinte

apache_request_headers()ou getallheaders()não parece colocar em maiúscula os nomes dos cabeçalhos quando testei. Eles estão retornando exatamente como eu passo do lado do cliente. Então, por que você está capitalizando nomes de cabeçalho em uma função de substituição?
Rineez

22

Desde o PHP 5.4.0 você pode usar a getallheadersfunção que retorna todos os cabeçalhos de solicitação como uma matriz associativa:

var_dump(getallheaders());

// array(8) {
//   ["Accept"]=>
//   string(63) "text/html[...]"
//   ["Accept-Charset"]=>
//   string(31) "ISSO-8859-1[...]"
//   ["Accept-Encoding"]=>
//   string(17) "gzip,deflate,sdch"
//   ["Accept-Language"]=>
//   string(14) "en-US,en;q=0.8"
//   ["Cache-Control"]=>
//   string(9) "max-age=0"
//   ["Connection"]=>
//   string(10) "keep-alive"
//   ["Host"]=>
//   string(9) "localhost"
//   ["User-Agent"]=>
//   string(108) "Mozilla/5.0 (Windows NT 6.1; WOW64) [...]"
// }

Anteriormente, essa função funcionava apenas quando o PHP estava sendo executado como um módulo Apache / NSAPI.


20
Estou usando-o no PHP-FPM 5.5 e NGINX. getallheaders () não existe.
CMCDragonkai

@CMCDragonkai no FPM como você conseguiu as informações do cabeçalho?
Ajit Singh

5

strtolowerNa falta de várias soluções propostas, o RFC2616 (HTTP / 1.1) define os campos de cabeçalho como entidades que não diferenciam maiúsculas de minúsculas. A coisa toda, não apenas o valor parte .

Então, sugestões como apenas analisar HTTP_ entradas estão erradas.

Melhor seria assim:

if (!function_exists('getallheaders')) {
    foreach ($_SERVER as $name => $value) {
        /* RFC2616 (HTTP/1.1) defines header fields as case-insensitive entities. */
        if (strtolower(substr($name, 0, 5)) == 'http_') {
            $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
        }
    }
    $this->request_headers = $headers;
} else {
    $this->request_headers = getallheaders();
}

Observe as diferenças sutis com sugestões anteriores. A função aqui também funciona em php-fpm (+ nginx).


1
Onde exatamente o RFC 2616 declara que os valores dos campos não diferenciam maiúsculas de minúsculas? Ele afirma explicitamente que "a data HTTP diferencia maiúsculas de minúsculas" - e isso entra no Datecabeçalho - e que "os valores de parâmetro [texto em Tipo de conteúdo após ponto e vírgula] podem ou não diferenciar maiúsculas de minúsculas". Portanto, considerando que há pelo menos dois cabeçalhos com valores que diferenciam maiúsculas de minúsculas, parece que você está errado.
Joker_vD 26/06

HTTP header fields, which include general-header (section 4.5), request-header (section 5.3), response-header (section 6.2), and entity-header (section 7.1) fields, follow the same generic format as that given in Section 3.1 of RFC 822 [9]. Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive. Então eu acho que você está errado.
Glenn Plas

4
Os nomes dos campos não diferenciam maiúsculas de minúsculas. Não há nada sobre valores de campo neste parágrafo, enquanto outras partes do documento informam explicitamente sobre valores de campo com distinção entre maiúsculas e minúsculas.
Joker_vD 26/06

1
Por que vocês estão substituindo sublinhado por espaço e espaço por traço? isso não funcionaria: $ headers [ucwords (strtolower (substr ($ name, 5)))] = $ value; ?
temirbek

5

Passe um nome de cabeçalho para esta função para obter seu valor sem usar o forloop. Retorna nulo se o cabeçalho não for encontrado.

/**
 * @var string $headerName case insensitive header name
 *
 * @return string|null header value or null if not found
 */
function get_header($headerName)
{
    $headers = getallheaders();
    return isset($headerName) ? $headers[$headerName] : null;
}

Nota: isso funciona apenas com o servidor Apache, consulte: http://php.net/manual/en/function.getallheaders.php

Nota: esta função processará e carregará todos os cabeçalhos na memória e terá menos desempenho do que um forloop.


função tem erro, substitua $ pHeaderKey para $ headerKey
Tegos

4

Para simplificar, eis como você pode obter exatamente o que deseja:

Simples:

$headerValue = $_SERVER['HTTP_X_REQUESTED_WITH'];

ou quando você precisar obter um de cada vez:

<?php
/**
 * @param $pHeaderKey
 * @return mixed
 */
function get_header( $pHeaderKey )
{
    // Expanded for clarity.
    $headerKey = str_replace('-', '_', $pHeaderKey);
    $headerKey = strtoupper($headerKey);
    $headerValue = NULL;
    // Uncomment the if when you do not want to throw an undefined index error.
    // I leave it out because I like my app to tell me when it can't find something I expect.
    //if ( array_key_exists($headerKey, $_SERVER) ) {
    $headerValue = $_SERVER[ $headerKey ];
    //}
    return $headerValue;
}
// X-Requested-With mainly used to identify Ajax requests. Most JavaScript frameworks
// send this header with value of XMLHttpRequest, so this will not always be present.
$header_x_requested_with = get_header( 'X-Requested-With' );

Os outros cabeçalhos também estão na matriz super global $ _SERVER, você pode ler sobre como acessá-los aqui: http://php.net/manual/en/reserved.variables.server.php


Comparando com outras respostas, parece que sua função não funcionará, pois ela não é HTTP_$headerKey
anexada

3

Eu estava usando o CodeIgniter e usei o código abaixo para obtê-lo. Pode ser útil para alguém no futuro.

$this->input->get_request_header('X-Requested-With');

Isso foi. Porém, sabia sobre o método get_request_header (), mas não tinha certeza de que eu poderia usar o nome do cabeçalho como está, ou seja, sem ter que alterar hífens para sublinhados.
Valkay

Ainda bem que ajudou. Felicidades.
Rajesh

1

Aqui está como eu estou fazendo isso. Você precisa obter todos os cabeçalhos se $ header_name não for passado:

<?php
function getHeaders($header_name=null)
{
    $keys=array_keys($_SERVER);

    if(is_null($header_name)) {
            $headers=preg_grep("/^HTTP_(.*)/si", $keys);
    } else {
            $header_name_safe=str_replace("-", "_", strtoupper(preg_quote($header_name)));
            $headers=preg_grep("/^HTTP_${header_name_safe}$/si", $keys);
    }

    foreach($headers as $header) {
            if(is_null($header_name)){
                    $headervals[substr($header, 5)]=$_SERVER[$header];
            } else {
                    return $_SERVER[$header];
            }
    }

    return $headervals;
}
print_r(getHeaders());
echo "\n\n".getHeaders("Accept-Language");
?>

Parece-me muito mais simples do que a maioria dos exemplos dados em outras respostas. Isso também obtém o método (GET / POST / etc.) E o URI solicitado ao obter todos os cabeçalhos que podem ser úteis se você estiver tentando usá-lo no log.

Aqui está a saída:

Array ( [HOST] => 127.0.0.1 [USER_AGENT] => Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0 [ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 [ACCEPT_LANGUAGE] => en-US,en;q=0.5 [ACCEPT_ENCODING] => gzip, deflate [COOKIE] => PHPSESSID=MySessionCookieHere [CONNECTION] => keep-alive )

en-US,en;q=0.5

0

Aqui está uma maneira fácil de fazer isso.

// echo get_header('X-Requested-With');
function get_header($field) {
    $headers = headers_list();
    foreach ($headers as $header) {
        list($key, $value) = preg_split('/:\s*/', $header);
        if ($key == $field)
            return $value;
    }
}

Não são os cabeçalhos enviados?
CMCDragonkai

@CMCDragonkai Não "headers_list () irá retornar uma lista de cabeçalhos para serem enviados para o navegador / cliente" - php.net/manual/en/function.headers-list.php
kehers

2
Sim. Foi isso que eu quis dizer.
CMCDragonkai # 9/13

1
A pergunta está solicitando cabeçalhos enviados ao servidor. Eles são os cabeçalhos da solicitação.
CMCDragonkai

1
A origem e o destino, ao usar termos como "enviado", "fora", "para", "de", são relativos ao contexto em que esses termos são usados. Nesta resposta, o exemplo mostra o PHP em execução no servidor . E, a pergunta do OP também referenciava o PHP do lado do servidor. Portanto, @CMCDragonkai e MichaelLeany estão corretos. Esta é uma resposta ruim. "enviado", neste contexto, significa "cabeçalhos de resposta HTTP enviados do servidor". kehers está comentando do ponto de vista do cliente, mas tanto a resposta quanto a pergunta do OP são do ponto de vista do servidor.
Evan de la Cruz

0

Este pequeno trecho de PHP pode ser útil para você:

<?php
foreach($_SERVER as $key => $value){
echo '$_SERVER["'.$key.'"] = '.$value."<br />";
}
?>

0
function getCustomHeaders()
{
    $headers = array();
    foreach($_SERVER as $key => $value)
    {
        if(preg_match("/^HTTP_X_/", $key))
            $headers[$key] = $value;
    }
    return $headers;
}

Eu uso essa função para obter os cabeçalhos personalizados, se o cabeçalho começa em "HTTP_X_", pressionamos a matriz :)


0

se apenas uma chave for necessária para recuperar, por exemplo, o "Host"endereço é necessário, então podemos usar

apache_request_headers()['Host']

Para que possamos evitar loops e alinhá-los às saídas de eco


Começando com o PHP 5.4. Na versão 5.3, essa sintaxe causará um erro.
Robin K

isso é testado com PHP 7.1
Dickens AS

0

PHP 7: Operador de coalescência nula

//$http = 'SCRIPT_NAME';
$http = 'X_REQUESTED_WITH';
$http = strtoupper($http);
$header = $_SERVER['HTTP_'.$http] ?? $_SERVER[$http] ?? NULL;

if(is_null($header)){
    die($http. ' Not Found');
}
echo $header;

-1

Este trabalho se você tiver um servidor Apache

Código PHP:

$headers = apache_request_headers();

foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
}

Resultado:

Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0
Host: www.example.com
Connection: Keep-Alive
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.