PHP'de herhangi bir istek başlığını nasıl okuyabilirim


271

PHP'de herhangi bir başlığı nasıl okumalıyım?

Özel başlık Örneğin: X-Requested-With.

Yanıtlar:


345

EĞER : tüm başlıklar yerine yalnızca tek bir başlığa ihtiyacınız vardır , en hızlı yöntem:

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


ELSE IF : PHP'yi Apache modülü olarak veya PHP 5.4'ten itibaren FastCGI (basit yöntem) kullanarak çalıştırırsınız:

apache_request_headers ()

<?php
$headers = apache_request_headers();

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


ELSE: Başka bir durumda şunları kullanabilirsiniz (kullanıcı arazisi uygulaması):

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


Ayrıca Bakınız :
getallheaders () - (PHP> = 5.4) platformlar arası sürüm apache_request_headers() apache_response_headers () - Diğer HTTP yanıt başlıklarını alır.
headers_list () - Gönderilecek başlıkların listesini alır.


3
Bu sadece Apache sunucusunu kullanırken olduğunu varsayalım ... OP bunu bildirmek gerekebilir :)
alex

12
Amatörlerin% 82'sini umursamıyorum. Profesyonel kurulumları önemsiyorum. Doğru durumda olan hiç kimse mod_php'de yüksek trafikli site çalıştırmayı denemez.
vartec

11
@Jacco Evet, ve bence bu aşağı oy için mükemmel bir neden. Herhangi bir zamanda en iyi cevap kaldırılmalı ve kötü cevaplar azaltılmalıdır. Bu bir tarihsel çözüm sitesi değil :-)
Thomas Jensen

3
@ThomasJensen Bazılarının diğer başlıklarda veya tüm başlıklarda etkileşime girebileceğini ve özellikle 'HTTP_X_REQUESTED_WITH' içinde değil; Cevap kesinlikle doğrudur ve Jacco açıkça sadece apache için çalıştığını belirtmiştir; Bazı senaryolarda en iyi / en performanslı çözümün iniş-çıkış IMO'su için bir neden olmaması.
Sebastian Hoffmann

1
@Paranaix A: Ne demek istediğinizi bilmiyorum, cevabın kapsamını eleştirmedim ve mantığınız tam olarak bu soruyu cevaplayarak cevabımı neden başlattığım ve daha fazla bilgi için daha genel bilgi ve bağlantılar ile detaylandırdım . B: Hala apache_request_headers () kullanımını teşvik etmeniz gerektiğini düşünmüyorum. Bu soruyu bulan yeni başlayanlar, daha iyi işlevler olduğunda utanç verici bir IMO olan soruyu kullanmaya başlayacaktır.
Thomas Jensen

371
$_SERVER['HTTP_X_REQUESTED_WITH']

RFC3875 , 4.1.18 :

İsimlerle başlayan meta değişkenler, HTTP_kullanılan protokol HTTP ise, istemci istek başlığı alanlarından okunan değerleri içerir. HTTP üstbilgisi alan adı büyük harfe dönüştürülür, tüm tekrarlamalarla -değiştirilir _ve HTTP_meta değişken adını vermeyi tercih eder.


6
Herhangi bir sunucunun $_SERVERdeğişkenin her başlığını koymasını bekleyebilir miyim ? Php.net/manual/en/reserved.variables.server.php adresindeki PHP belgeleri, orada olacağından emin olabileceğimiz konusunda kaçamaklıdır.
Mark Amery

4
Bu, özellikle PHP-fpm'de (veya cgi'de) (her zaman) çalışmaz. Bu üstbilgi her zaman PHP içinden alınamaz.
Glenn Plas

Bu çözümü kullanarak yalnızca istek başlıklarının bazılarını görüyorum ve bu durumda istediğim şeyi göremiyorum. Chrome bir cache-controlbaşlık gönderiyor , ancak bunu hiçbir yerde göremiyorum $_SERVER. HTTP_"HTTP_ACCEPT" ve "HTTP_UPGRADE_INSECURE_REQUESTS" ve "HTTP_USER_AGENT" (diğerleri arasında) dahil olmak üzere ön ekli birkaç üstbilgi görüyorum . Ama "önbellek kontrolü" için hiçbir şey "pragma" için hiçbir şey. Bu, büyük / küçük harf veya HTTP_önek ne olursa olsun . Bir şey mi kaçırıyorum?
Evan de la Cruz

@EvandelaCruz: leserged.online.fr/phpinfo.php Burada görüyorum:_SERVER["HTTP_CACHE_CONTROL"] max-age=0
Quassnoi

hmmm, teşekkürler ... Bu benim wamp dev sunucusunda ve PHP bir Apache modülü olarak çalıştığını düşünüyorum ama emin değilim. Prod kutumu FPM ile kontrol edeyim ve neden burada wamp'ta göremediğimi anlayabiliyor muyum bakalım ...
Evan de la Cruz

48

$_SERVERGlobal değişken içindeki tüm HTTP üstbilgilerini, HTTP_büyük harflerle yazılmış ve kısa çizgilerle (-) alt çizgi (_) ile değiştirilmiş olarak bulmalısınız .

Örneğin şurada X-Requested-Withbulabilirsiniz:

$_SERVER['HTTP_X_REQUESTED_WITH']

$_SERVERDeğişkenden ilişkilendirilebilir bir dizi oluşturmak uygun olabilir . Bu çeşitli stillerle yapılabilir, ancak işte devirli tuşlar çıkaran bir işlev:

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

Şimdi sadece $headers['XRequestedWith']istenen başlığı almak için kullanın .

PHP el kitabı $_SERVER: http://php.net/manual/en/reserved.variables.server.php


3
Bence en iyi cevap, Thomas'ın Quassnoi'nin nihai sonucu ile açıklaması. İlişkilendirilebilir bir dizi genellikle ihtiyaç duyulan şey değildir ve parseRequestHeaders()işlevi okumaktan basit bir çözüm bulmak çok kolay değildir . Böyle bir ilişkisel dizi gerekiyorsa, IMO apache işlevi en iyi seçenektir, çünkü tam olarak karıştırılmış bir CamelCase sürümü yerine alınan üstbilgileri döndürür. (Ayrıca PHP 5.4'ten itibaren artık yalnızca Apache olmadığını unutmayın.)
Brilliand

Bunu 2 yıl 11 ay daha hızlı cevaplarsanız, bu cevap 200'den fazla oy kullanır.
DividedByZero

apache_request_headers()veya getallheaders()test ettiğimde Başlık adlarını büyük harfle yazmıyor gibi görünüyor. Müşteri tarafından geçerken tam olarak geri dönüyorlar. Öyleyse neden böyle bir değiştirme işlevinde başlık adlarını büyük harfle yazıyorsunuz?
rineez

22

PHP 5.4.0'dan beri getallheaders, tüm istek başlıklarını ilişkilendirilebilir bir dizi olarak döndüren işlevi kullanabilirsiniz :

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

Daha önce bu işlev yalnızca PHP bir Apache / NSAPI modülü olarak çalışırken çalıştı.


20
PHP-FPM 5.5 ve NGINX üzerinde kullanıyorum. getallheaders () mevcut değil.
CMCDragonkai

@CMCDragonkai FPM'de başlık bilgisini nasıl aldınız?
Ajit Singh

5

strtolowerönerilen çözümlerin birçoğunda eksik olan RFC2616 (HTTP / 1.1), başlık alanlarını büyük / küçük harfe duyarlı olmayan varlıklar olarak tanımlar. Her şey, sadece değer kısmı değil.

Bu nedenle, yalnızca HTTP_ girişlerini ayrıştırma gibi öneriler yanlıştır.

Daha iyisi şöyle olur:

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

Önceki önerilerdeki küçük farklılıklara dikkat edin. Buradaki işlev php-fpm (+ nginx) üzerinde de çalışır.


1
RFC 2616, alan değerlerinin büyük / küçük harfe duyarlı olmadığını tam olarak nerede belirtir? "HTTP-date büyük / küçük harfe duyarlıdır" - ve bunun Datebaşlığa girer - ve "Parametre değerleri [noktalı virgül sonrası Content-Type içindeki metin] büyük / küçük harfe duyarlı olabilir veya olmayabilir". Dolayısıyla, büyük / küçük harfe duyarlı değerlere sahip en az iki başlık olduğu için yanıldığınız anlaşılıyor.
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. Sanırım yanılıyorsun.
Glenn Plas

4
Alan adları büyük / küçük harfe duyarlı değildir. Bu paragrafta alan değerleri hakkında hiçbir şey yoktur , ancak belgenin diğer bölümleri büyük / küçük harfe duyarlı alan değerlerini açıklar.
Joker_vD

1
Neden hepiniz altı çizili uzaya sonra uzaya fırlayacak? bu sadece işe yaramaz: $ headers [ucwords (strtolower (substr ($ name, 5)))]] $ $; ?
temirbek

5

Döngüsünü kullanmadan değerini almak için bu işleve bir başlık adı foriletin. Başlık bulunmazsa null değerini döndürür.

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

Not: Bu yalnızca Apache sunucusuyla çalışır, bkz: http://php.net/manual/en/function.getallheaders.php

Not: Bu işlev tüm başlıkları işleyip belleğe yükler ve bir fordöngüden daha az performans gösterir .


fonksiyon yerine, hata var $ pHeaderKey için $ headerKey
TEGOS

4

İşleri basitleştirmek için, sadece istediğinizi nasıl elde edebileceğiniz aşağıda açıklanmıştır:

Basit:

$headerValue = $_SERVER['HTTP_X_REQUESTED_WITH'];

veya her seferinde bir tane almanız gerektiğinde:

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

Diğer başlıklar da süper küresel dizide $ _SERVER, onlara nasıl ulaşacağınızı buradan okuyabilirsiniz: http://php.net/manual/en/reserved.variables.server.php


Diğer cevaplara karşılaştırılması Eğer iş o başa ekleyerek gelmez olmaz olarak işlev gibi görünüyor HTTP_için$headerKey
EECOLOR

3

CodeIgniter kullanıyordum ve almak için aşağıdaki kodu kullandım. Gelecekte biri için yararlı olabilir.

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

Öyleydi. Olsa get_request_header () yöntemi hakkında biliyordu, ancak üstbilgi adını olduğu gibi, yani alt çizgilere tire değiştirmek zorunda kalmadan kullanabilirsiniz emin değildi.
Valkay

Yardımcı oldu sevindim. Şerefe.
Rajesh

1

İşte böyle yapıyorum. $ Header_name geçilmezse tüm üstbilgileri almanız gerekir:

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

Benim için diğer cevaplarda verilen örneklerin çoğundan çok daha basit görünüyor. Bu aynı zamanda yöntemi (GET / POST / etc.) Ve tüm üstbilgileri alırken istenen URI'yi günlüğe kaydetmede kullanmaya çalışıyorsanız faydalı olabilir.

İşte çıktı:

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

İşte bunu yapmanın kolay bir yolu.

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

Gönderilen başlıklar değil mi?
CMCDragonkai

"Headers_list (), tarayıcıya / istemciye gönderilecek başlıkların bir listesini döndürecektir" - php.net/manual/en/function.headers-list.php
kehers

2
Evet. Demek istediğim şey o.
CMCDragonkai

1
Soru, sunucuya gönderilen üstbilgileri sormaktır. Bunlar istek üstbilgileridir.
CMCDragonkai

1
Kaynak ve hedef, "gönderilen", "çıkış", "-", "arasındaki" gibi terimler kullanıldığında, bu terimlerin kullanıldığı bağlama göre olur. Bu cevapta örnek sunucuda çalışan PHP'yi göstermektedir . OP'nin sorusu ayrıca sunucu tarafı PHP'ye de atıfta bulundu. Bu nedenle, @CMCDragonkai ve MichaelLeany doğrudur. Bu kötü bir cevap. "gönderilen", bu bağlamda, "sunucudan gönderilen HTTP yanıt üstbilgileri" anlamına gelir. kehers, müşterinin bakış açısından yorum yapıyor, ancak hem cevabı hem de OP'nin sorusu sunucunun bakış açısından.
Evan de la Cruz

0

Bu küçük PHP snippet'i size yardımcı olabilir:

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

Bu işlevi özel üstbilgileri almak için kullanıyorum, üstbilgi "HTTP_X_" den başlıyorsa diziye giriyoruz :)


0

yalnızca bir anahtarın alınması gerekiyorsa, örneğin "Host"adres gerekliyse,

apache_request_headers()['Host']

Böylece döngülerden kaçınabilir ve yankı çıktılarına satır içi koyabiliriz


PHP 5.4 ile başlıyor. 5.3'te, bu sözdizimi bir hataya neden olacaktır.
Robin K

Bu PHP 7.1 ile test edilmiştir
Dickens AS

0

PHP 7: Boş Birleştirme İşleci

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

Bir Apache sunucunuz varsa bu çalışma

PHP Kodu:

$headers = apache_request_headers();

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

Sonuç:

Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0
Host: www.example.com
Connection: Keep-Alive
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.