Wie lese ich einen Anforderungsheader in PHP?


271

Wie soll ich einen Header in PHP lesen?

Zum Beispiel der benutzerdefinierte Header : X-Requested-With.

Antworten:


345

IF : Sie benötigen nur einen einzigen Header. Anstelle aller Header ist die schnellste Methode:

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


SONST WENN : Sie führen PHP als Apache-Modul oder ab PHP 5.4 mit FastCGI (einfache Methode) aus:

apache_request_headers ()

<?php
$headers = apache_request_headers();

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


ELSE: In jedem anderen Fall können Sie Folgendes verwenden (Userland-Implementierung):

<?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";
}


Siehe auch :
getallheaders () - (PHP> = 5.4) plattformübergreifende Edition Alias ​​von apache_request_headers() apache_response_headers () - Ruft alle HTTP- Antwortheader ab .
headers_list () - Ruft eine Liste der zu sendenden Header ab.


3
Ich nehme an, dies nur dann , wenn der Apache - Server mit ... Möglicherweise müssen Sie das OP wissen lassen , dass :)
alex

11
82% der Amateure interessieren mich nicht. Ich interessiere mich für professionelle Installationen. Niemand in der richtigen Stimmung würde versuchen, eine Site mit hohem Datenverkehr auf mod_php auszuführen.
Vartec

11
@Jacco Ja, und ich denke, das ist ein perfekter Grund für ein Downvoting. Zu jedem Zeitpunkt sollte die beste Antwort bewertet und schlechte Antworten abgelehnt werden. Dies ist kein Ort historischer Lösungen :-)
Thomas Jensen

3
@ThomasJensen Bedenken Sie jedoch, dass einige möglicherweise an anderen oder allen Headern interessiert sind und nicht speziell an 'HTTP_X_REQUESTED_WITH'; Die Antwort ist absolut richtig und Jacco hat ausdrücklich erklärt, dass es nur bei Apachen funktioniert; Dass es in einigen Szenarien nicht die beste / leistungsstärkste Lösung ist, ist kein Grund für eine Ablehnung der IMO.
Sebastian Hoffmann

1
@Paranaix A: Ich weiß nicht, was Sie meinen, ich habe das Ausmaß der Antwort nicht kritisiert und Ihre Argumentation ist genau der Grund, warum ich meine Antwort mit der Beantwortung der spezifischen Frage begonnen und dann mit allgemeineren Kenntnissen und Links für weitere Informationen ausgearbeitet habe . B: Ich denke immer noch nicht, dass Sie die Verwendung von apache_request_headers () fördern sollten. Neulinge, die diese Frage finden, werden sie verwenden, was IMO schade ist, wenn bessere Funktionen existieren.
Thomas Jensen

371
$_SERVER['HTTP_X_REQUESTED_WITH']

RFC3875 , 4.1.18:

Metavariablen mit Namen, die mit beginnen, HTTP_enthalten Werte, die aus den Headerfeldern für Clientanforderungen gelesen wurden, wenn das verwendete Protokoll HTTP ist. Der Name des HTTP-Headerfelds wird in Großbuchstaben konvertiert, alle Vorkommen werden durch -ersetzt _und der HTTP_Metavariablenname wird vorangestellt.


6
Kann ich zuverlässig erwarten, dass ein Server jeden Header in die $_SERVERVariable einfügt? Die PHP-Dokumentation unter php.net/manual/en/reserved.variables.server.php weicht aus, was wir sicher sein können, dass es dort sein wird.
Mark Amery

4
Dies wird (immer) nicht funktionieren, insbesondere in PHP-fpm (oder cgi). Dieser Header ist in PHP nicht immer verfügbar.
Glenn Plas

Mit dieser Lösung werden nur einige der Anforderungsheader angezeigt, und in diesem Fall wird der gewünschte nicht angezeigt. Chrome sendet einen cache-controlHeader, aber ich sehe ihn nirgendwo in $_SERVER. Ich sehe mehrere Header mit dem Präfix HTTP_"HTTP_ACCEPT", "HTTP_UPGRADE_INSECURE_REQUESTS" und "HTTP_USER_AGENT" (unter anderem). Aber nichts für "Cache-Kontrolle", auch nichts für "Pragma". Dies ist unabhängig von Groß- und Kleinschreibung oder HTTP_Präfix. Vermisse ich etwas
Evan de la Cruz

@ EvandelaCruz: leserged.online.fr/phpinfo.php Ich sehe es hier:_SERVER["HTTP_CACHE_CONTROL"] max-age=0
Quassnoi

hmmm, danke ... Das ist auf meinem Wamp Dev Server und ich denke PHP läuft als Apache Modul, aber ich bin mir nicht sicher. Lassen Sie mich meine Produktbox mit FPM überprüfen und sehen, ob ich herausfinden kann, warum ich sie hier auf Wamp nicht sehe ...
Evan de la Cruz

48

Sie sollten alle HTTP-Header in der $_SERVERglobalen Variablen finden, der HTTP_Großbuchstaben vorangestellt sind und durch Bindestriche (-) ersetzt werden, die durch Unterstriche (_) ersetzt werden.

Zum Beispiel finden Sie Ihre X-Requested-Within:

$_SERVER['HTTP_X_REQUESTED_WITH']

Es kann zweckmäßig sein, aus der $_SERVERVariablen ein assoziatives Array zu erstellen . Dies kann in verschiedenen Stilen erfolgen, aber hier ist eine Funktion, die Kamelschlüssel ausgibt:

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

Verwenden Sie jetzt einfach $headers['XRequestedWith'], um den gewünschten Header abzurufen.

PHP-Handbuch unter $_SERVER: http://php.net/manual/en/reserved.variables.server.php


3
Die beste Antwort ist meiner Meinung nach die Erklärung von Thomas mit dem Endergebnis von Quassnoi. Ein assoziatives Array ist normalerweise nicht erforderlich, und es ist nicht sehr einfach, die einfache Lösung aus dem Lesen der parseRequestHeaders()Funktion zu ermitteln. Wenn ein solches assoziatives Array benötigt wird, ist IMO die Apache-Funktion die beste Option, da sie genau die empfangenen Header anstelle einer verstümmelten CamelCase-Version zurückgibt. (Beachten Sie auch, dass es ab PHP 5.4 nicht mehr nur Apache ist.)
Brilliand

Hätten Sie diese 2 Jahre und 11 Monate schneller beantwortet, hätte diese Antwort mehr als 200 positive Stimmen.
DividedByZero

apache_request_headers()oder getallheaders()scheint die Header-Namen beim Testen nicht groß zu schreiben. Sie kehren genau so zurück, wie ich von der Client-Seite komme. Warum setzen Sie dann Headernamen in einer solchen Ersetzungsfunktion groß?
Rineez

22

Seit PHP 5.4.0 können Sie eine getallheadersFunktion verwenden, die alle Anforderungsheader als assoziatives Array zurückgibt:

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) [...]"
// }

Früher funktionierte diese Funktion nur, wenn PHP als Apache / NSAPI-Modul ausgeführt wurde.


20
Ich benutze es auf PHP-FPM 5.5 und NGINX. getallheaders () existiert nicht.
CMCDragonkai

@CMCDragonkai in FPM Wie haben Sie die Header-Informationen erhalten?
Ajit Singh

5

strtolowerDa in mehreren der vorgeschlagenen Lösungen RFC2616 (HTTP / 1.1) fehlt, werden Headerfelder als Entitäten definiert, bei denen die Groß- und Kleinschreibung nicht berücksichtigt wird. Das Ganze, nicht nur der Wert .

Vorschläge wie das Parsen von HTTP_- Einträgen sind also falsch.

Besser wäre so:

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();
}

Beachten Sie die subtilen Unterschiede zu früheren Vorschlägen. Die Funktion funktioniert hier auch mit php-fpm (+ nginx).


1
Wo genau gibt RFC 2616 an, dass bei Feldwerten die Groß- und Kleinschreibung nicht berücksichtigt wird? Es wird explizit angegeben, dass "HTTP-Datum zwischen Groß- und Kleinschreibung unterscheidet" - und dies geht in den DateHeader - und dass "Parameterwerte [Text in Inhaltstyp nach Semikolon] möglicherweise zwischen Groß- und Kleinschreibung unterscheiden oder nicht". Angesichts der Tatsache, dass es mindestens zwei Header mit Werten gibt, bei denen zwischen Groß- und Kleinschreibung unterschieden wird, scheinen Sie sich zu irren.
Joker_vD

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. Also ich denke du liegst falsch.
Glenn Plas

4
Feldnamen sind Groß- und Kleinschreibung. In diesem Absatz wird nichts über Feldwerte gesagt, während andere Teile des Dokuments explizit über Feldwerte mit Groß- und Kleinschreibung berichten.
Joker_vD

1
Warum ersetzt ihr alle Unterstreichung in Leerzeichen und dann Leerzeichen in Strich? würde das nicht einfach funktionieren: $ headers [ucwords (strtolower (substr ($ name, 5)))] = $ value; ?
Temirbek

5

Übergeben Sie dieser Funktion einen Headernamen, um den Wert ohne Verwendung der forSchleife abzurufen. Gibt null zurück, wenn der Header nicht gefunden wurde.

/**
 * @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;
}

Hinweis: Dies funktioniert nur mit Apache-Servern, siehe: http://php.net/manual/en/function.getallheaders.php

Hinweis: Diese Funktion verarbeitet und lädt alle Header in den Speicher und ist weniger performant als eine forSchleife.


Funktion hat Fehler, ersetzen Sie $ pHeaderKey zu $ headerKey
Tegos

4

Um die Sache zu vereinfachen, können Sie wie folgt genau das bekommen, was Sie wollen:

Einfach:

$headerValue = $_SERVER['HTTP_X_REQUESTED_WITH'];

oder wenn Sie einen nach dem anderen benötigen:

<?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' );

Die anderen Header befinden sich ebenfalls im superglobalen Array $ _SERVER. Informationen dazu finden Sie hier: http://php.net/manual/en/reserved.variables.server.php


Im Vergleich zu anderen Antworten scheint es, dass HTTP_$headerKey
Ihre

3

Ich habe CodeIgniter verwendet und den folgenden Code verwendet, um ihn abzurufen. Kann in Zukunft für jemanden nützlich sein.

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

Es war. Ich wusste zwar etwas über die Methode get_request_header (), war mir aber nicht sicher, ob ich den Headernamen unverändert verwenden konnte, dh ohne Bindestriche in Unterstriche ändern zu müssen.
Valkay

Ich bin froh, dass es geholfen hat. Prost.
Rajesh

1

Hier ist, wie ich es mache. Sie müssen alle Header abrufen, wenn $ header_name nicht übergeben wird:

<?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");
?>

Es sieht für mich viel einfacher aus als die meisten Beispiele in anderen Antworten. Dadurch werden auch die Methode (GET / POST / etc.) Und die angeforderte URI abgerufen, wenn alle Header abgerufen werden. Dies kann hilfreich sein, wenn Sie versuchen, sie für die Protokollierung zu verwenden.

Hier ist die Ausgabe:

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

Hier ist eine einfache Möglichkeit, dies zu tun.

// 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;
    }
}

Sind das nicht Header, die verschickt werden?
CMCDragonkai

@CMCDragonkai Nr. "Headers_list () gibt eine Liste der Header zurück, die an den Browser / Client gesendet werden sollen" - php.net/manual/en/function.headers-list.php
kehers

2
Ja. Das ist es was ich meinte.
CMCDragonkai

1
Die Frage lautet nach Headern, die an den Server gesendet werden. Sie sind die Anforderungsheader.
CMCDragonkai

1
Die Quelle und das Ziel sind bei Verwendung von Begriffen wie "gesendet", "out", "to", "from" relativ zu dem Kontext, in dem diese Begriffe verwendet werden. In dieser Antwort zeigt das Beispiel, wie PHP auf dem Server ausgeführt wird . Die Frage des OP bezog sich auch auf serverseitiges PHP. Daher sind @CMCDragonkai und MichaelLeany korrekt. Das ist eine schlechte Antwort. "gesendet" bedeutet in diesem Zusammenhang "vom Server gesendete HTTP-Antwortheader". kehers kommentiert aus Sicht des Clients, aber sowohl seine Antwort als auch die Frage des OP sind aus Sicht des Servers.
Evan de la Cruz

0

Dieses kleine PHP-Snippet kann für Sie hilfreich sein:

<?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;
}

Ich benutze diese Funktion, um die benutzerdefinierten Header zu erhalten. Wenn der Header von "HTTP_X_" ausgeht, drücken wir das Array ein :)


0

Wenn zum Abrufen nur ein Schlüssel erforderlich ist, z. B. eine "Host"Adresse, können wir verwenden

apache_request_headers()['Host']

Damit wir Schleifen vermeiden und in die Echoausgänge einbinden können


Beginnend mit PHP 5.4. In 5.3 verursacht diese Syntax einen Fehler.
Robin K

Dies wird mit PHP 7.1
Dickens AS

0

PHP 7: Null-Koaleszenz-Operator

//$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

Dies funktioniert, wenn Sie einen Apache-Server haben

PHP-Code:

$headers = apache_request_headers();

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

Ergebnis:

Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0
Host: www.example.com
Connection: Keep-Alive
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.