Bagaimana cara membaca header permintaan apa pun di PHP

271

Bagaimana saya membaca header di PHP?

Misalnya kustom header: X-Requested-With.

Sabya
sumber

Jawaban:

345

JIKA : Anda hanya perlu satu tajuk, alih-alih semua tajuk, metode tercepat adalah:

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


LAIN JIKA : Anda menjalankan PHP sebagai modul Apache atau, pada PHP 5.4, menggunakan FastCGI (metode sederhana):

apache_request_headers ()

<?php
$headers = apache_request_headers();

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


ELSE: Dalam hal lain, Anda dapat menggunakan (implementasi userland):

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


Lihat Juga :
getallheaders () - (PHP> = 5.4) edisi lintas platform Alias ​​of apache_request_headers() apache_response_headers () - Ambil semua header respons HTTP.
headers_list () - Ambil daftar header yang akan dikirim.

Jacco
sumber
3
Saya menganggap ini adalah hanya ketika menggunakan server Apache ... mungkin perlu untuk membiarkan OP tahu bahwa :)
alex
12
Saya tidak peduli dengan 82% amatir. Saya peduli dengan instalasi profesional. Tidak ada orang yang berpikiran sehat akan mencoba menjalankan situs traffic tinggi di mod_php.
vartec
11
@Jacco Ya, dan saya pikir itu menjadi alasan yang sempurna untuk downvoting. Pada waktu tertentu, jawaban terbaik harus ditingkatkan dan jawaban buruk diturunkan. Ini bukan situs solusi historis :-)
Thomas Jensen
3
@ThomasJensen Pertimbangkan juga, bahwa beberapa mungkin diselingi di header lain atau semua dan tidak terutama di 'HTTP_X_REQUESTED_WITH'; Jawabannya benar mutlak dan Jacco dengan tegas menyatakan bahwa itu hanya berfungsi untuk apache; Bahwa itu dalam beberapa skenario bukan solusi terbaik / paling berkinerja tidak ada alasan untuk downvote IMO.
Sebastian Hoffmann
1
@Paranaix A: Saya tidak tahu apa yang Anda maksud, saya belum mengkritik sejauh mana jawaban dan alasan Anda adalah mengapa saya memulai jawaban saya dengan menjawab pertanyaan spesifik dan kemudian menguraikan dengan pengetahuan yang lebih umum dan tautan untuk informasi lebih lanjut . B: Saya masih tidak berpikir Anda harus mendorong penggunaan apache_request_headers (). Pemula yang menemukan pertanyaan ini akan mulai menggunakannya yang merupakan IMO yang memalukan ketika ada fungsi yang lebih baik.
Thomas Jensen
371
$_SERVER['HTTP_X_REQUESTED_WITH']

RFC3875 , 4.1.18:

Meta-variabel dengan nama yang diawali dengan HTTP_berisi nilai yang dibaca dari bidang header permintaan klien, jika protokol yang digunakan adalah HTTP. Nama bidang tajuk HTTP dikonversi ke huruf besar, memiliki semua kemunculan -diganti dengan _dan telah HTTP_ditambahkan untuk memberikan nama meta-variabel.

Quassnoi
sumber
6
Bisakah saya berharap server mana pun untuk menempatkan setiap header ke dalam $_SERVERvariabel? Dokumentasi PHP di php.net/manual/en/reserved.variables.server.php mengelak tentang apa yang bisa kita yakini ada di sana.
Mark Amery
4
Ini tidak akan (selalu) berfungsi, terutama dalam PHP-fpm (atau cgi). Header ini tidak selalu tersedia dari dalam PHP.
Glenn Plas
Menggunakan solusi ini, saya hanya melihat beberapa header permintaan, dan dalam hal ini, saya tidak melihat yang saya inginkan. Chrome mengirim cache-controltajuk, tapi saya tidak melihatnya di mana pun di $_SERVER. Saya memang melihat beberapa tajuk diawali dengan HTTP_, termasuk "HTTP_ACCEPT", dan "HTTP_UPGRADE_INSECURE_REQUESTS" dan "HTTP_USER_AGENT" (di antara beberapa lainnya). Tapi tidak ada untuk "kontrol cache" juga tidak ada untuk "pragma". Ini terlepas dari kasus atau HTTP_awalan. Apakah saya melewatkan sesuatu?
Evan de la Cruz
@EvandelaCruz: leserged.online.fr/phpinfo.php Saya melihatnya di sini:_SERVER["HTTP_CACHE_CONTROL"] max-age=0
Quassnoi
hmmm, terima kasih ... Ini ada di server dev wamp saya dan saya pikir PHP berjalan sebagai modul Apache tapi saya tidak yakin. Biarkan saya memeriksa kotak prod saya dengan FPM dan melihat apakah saya dapat mengetahui mengapa saya tidak melihatnya di sini ...
Evan de la Cruz
48

Anda harus menemukan semua header HTTP di $_SERVERvariabel global yang diawali dengan HTTP_huruf besar dan dengan tanda hubung (-) diganti dengan garis bawah (_).

Misalnya Anda X-Requested-Withdapat ditemukan di:

$_SERVER['HTTP_X_REQUESTED_WITH']

Mungkin nyaman untuk membuat array asosiatif dari $_SERVERvariabel. Ini bisa dilakukan dalam beberapa gaya, tapi di sini ada fungsi yang mengeluarkan kunci camelcased:

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

Sekarang cukup gunakan $headers['XRequestedWith']untuk mengambil header yang diinginkan.

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

Thomas Jensen
sumber
3
Jawaban terbaik, menurut saya, adalah penjelasan Thomas dengan hasil akhir Quassnoi. Array asosiatif biasanya bukan yang dibutuhkan, dan tidak mudah untuk menemukan solusi sederhana dari membaca parseRequestHeaders()fungsi. Jika array asosiatif seperti itu diperlukan, maka IMO fungsi apache adalah opsi terbaik, karena mengembalikan persis header yang diterima daripada versi CamelCase yang rusak. (Juga perhatikan bahwa pada PHP 5.4, tidak lagi hanya Apache.)
Brilliand
Apakah Anda telah menjawab ini 2 tahun dan 11 bulan lebih cepat, jawaban ini akan memiliki 200+ peningkatan.
DividedByZero
apache_request_headers()atau getallheaders()sepertinya tidak menggunakan nama judul saat saya menguji. Mereka kembali tepat ketika saya lulus dari sisi klien. Lalu mengapa Anda menggunakan nama judul dalam fungsi penggantian seperti itu?
rineez
22

Karena PHP 5.4.0 Anda dapat menggunakan getallheadersfungsi yang mengembalikan semua header permintaan sebagai array asosiatif:

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

Sebelumnya fungsi ini hanya berfungsi ketika PHP dijalankan sebagai modul Apache / NSAPI.

Salman A
sumber
20
Saya menggunakannya di PHP-FPM 5.5 dan NGINX. getallheaders () tidak ada.
CMCDragonkai
@ CMCDragonkai di FPM bagaimana Anda mendapat informasi header?
Ajit Singh
5

strtolowerkurang dalam beberapa solusi yang diusulkan, RFC2616 (HTTP / 1.1) mendefinisikan bidang header sebagai entitas case-insensitive. Semuanya, bukan hanya bagian nilai .

Jadi saran seperti hanya mem- parsing entri HTTP_ salah.

Lebih baik seperti ini:

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

Perhatikan perbedaan halus dengan saran sebelumnya. Fungsi di sini juga berfungsi di php-fpm (+ nginx).

Glenn Plas
sumber
1
Di mana tepatnya RFC 2616 menyatakan bahwa nilai bidang tidak peka huruf besar-kecil? Ini secara eksplisit menyatakan bahwa "HTTP-date case-sensitive" - ​​dan itu masuk ke Dateheader - dan bahwa "Nilai parameter [teks dalam Content-Type setelah titik koma] mungkin atau mungkin tidak peka huruf besar-kecil". Jadi mengingat setidaknya ada dua header dengan nilai case-sensitive, sepertinya Anda salah.
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. Jadi saya kira Anda salah.
Glenn Plas
4
Nama bidang tidak peka huruf besar-kecil. Tidak ada apa pun tentang nilai bidang dalam paragraf ini, sementara bagian lain dari dokumen secara eksplisit memberi tahu tentang nilai-nilai bidang peka huruf besar-kecil.
Joker_vD
1
Kenapa ya semua mengganti garis bawah ke spasi lalu spasi ke dasbor? tidakkah ini hanya bekerja: $ header [ucwords (strtolower (substr ($ name, 5)))] = $ value; ?
temirbek
5

Berikan nama tajuk ke fungsi ini untuk mendapatkan nilainya tanpa menggunakan forlingkaran. Mengembalikan nol jika tajuk tidak ditemukan.

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

Catatan: ini hanya berfungsi dengan server Apache, lihat: http://php.net/manual/en/function.getallheaders.php

Catatan: fungsi ini akan memproses dan memuat semua header ke memori dan itu kurang berkinerja daripada forloop.

Milap Kundalia
sumber
fungsi memiliki kesalahan, ganti $ pHeaderKey ke $ headerKey
Tegos
4

Untuk mempermudah, berikut ini cara mendapatkan yang Anda inginkan:

Sederhana:

$headerValue = $_SERVER['HTTP_X_REQUESTED_WITH'];

atau ketika Anda perlu mendapatkannya satu per satu:

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

Header lain juga ada dalam array super global $ _SERVER, Anda dapat membaca tentang cara mendapatkannya di sini: http://php.net/manual/en/reserved.variables.server.php

b01
sumber
Dibandingkan dengan jawaban lain, sepertinya Anda berfungsi tidak akan berfungsi karena tidak HTTP_$headerKey
bergantung
3

Saya menggunakan CodeIgniter dan menggunakan kode di bawah ini untuk mendapatkannya. Semoga bermanfaat bagi seseorang di masa depan.

$this->input->get_request_header('X-Requested-With');
Rajesh
sumber
Dulu. Tahu tentang metode get_request_header (), tetapi tidak yakin saya bisa menggunakan nama header apa adanya, yaitu tanpa harus mengubah tanda hubung ke garis bawah.
Valkay
Senang itu membantu. Bersulang.
Rajesh
1

Begini cara saya melakukannya. Anda harus mendapatkan semua tajuk jika $ header_name tidak lulus:

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

Bagiku itu terlihat jauh lebih sederhana daripada sebagian besar contoh yang diberikan dalam jawaban lain. Ini juga mendapatkan metode (GET / POST / dll.) Dan URI diminta ketika mendapatkan semua header yang dapat berguna jika Anda mencoba menggunakannya dalam log.

Inilah hasilnya:

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
Kue Jonny
sumber
0

Ini cara mudah untuk melakukannya.

// 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;
    }
}
kehers
sumber
Bukankah itu tajuk yang dikirim?
CMCDragonkai
@CMCDragonkai No. "headers_list () akan mengembalikan daftar header untuk dikirim ke browser / klien" - php.net/manual/en/function.headers-list.php
kehers
2
Ya. Itu yang saya maksud.
CMCDragonkai
1
Pertanyaannya adalah menanyakan tajuk yang dikirim ke server. Mereka adalah header permintaan.
CMCDragonkai
1
Sumber dan tujuan, ketika menggunakan istilah seperti "dikirim", "keluar", "ke", "dari", relatif terhadap konteks di mana istilah tersebut digunakan. Dalam jawaban ini, contoh menunjukkan PHP berjalan di server . Dan, pertanyaan OP juga merujuk PHP sisi server. Karenanya, @CMCDragonkai dan MichaelLeany benar. Ini jawaban yang buruk. "dikirim", dalam konteks ini, berarti "header respons HTTP yang dikirim dari server". kehers berkomentar dari sudut pandang klien, tetapi jawaban dan pertanyaan OP adalah dari sudut pandang server.
Evan de la Cruz
0

Cuplikan PHP kecil ini dapat membantu Anda:

<?php
foreach($_SERVER as $key => $value){
echo '$_SERVER["'.$key.'"] = '.$value."<br />";
}
?>
Technolust
sumber
0
function getCustomHeaders()
{
    $headers = array();
    foreach($_SERVER as $key => $value)
    {
        if(preg_match("/^HTTP_X_/", $key))
            $headers[$key] = $value;
    }
    return $headers;
}

Saya menggunakan fungsi ini untuk mendapatkan header kustom, jika header dimulai dari "HTTP_X_" kami mendorong dalam array :)

ZiTAL
sumber
0

jika hanya satu kunci yang diperlukan untuk diambil, Misalnya "Host"alamat diperlukan, maka kita dapat menggunakan

apache_request_headers()['Host']

Sehingga kita dapat menghindari loop dan meletakkannya sejajar dengan output echo

Dickens AS
sumber
Dimulai dengan PHP 5.4. Pada 5.3, sintaks ini akan menyebabkan kesalahan.
Robin K
ini diuji dengan PHP 7.1
Dickens AS
0

PHP 7: Null Coalesce 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;
Perancah
sumber
-1

Ini berfungsi jika Anda memiliki server Apache

Kode PHP:

$headers = apache_request_headers();

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

Hasil:

Accept: */*
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0
Host: www.example.com
Connection: Keep-Alive
Emanuel Nogueiras
sumber