ラボ > PHP:通信絡み、Laravel、Lumen

laravelで取得できないリクエストヘッダの取得(\Request::header()、getallheaders())

リクエストヘッダを取得するためにlaravelの「\Request::header()」を使っても取得できない項目がいる

作成日:2019-06-10, 更新日:2019-06-10

経緯

・リクエストヘッダに「〇〇〇_〇〇〇」っていう風な「_」付きの項目をセット
・laravelへセットした内容を投げる
・laravel側で値を取得するとリクエストヘッダに「〇〇〇_〇〇〇」がいない。

▼laravel側で値の取得

var_dump(\Request::header());

調査

あちこちでログ出力したり、var_dump()したり・・・大文字がダメなのか、変な記号が入っているのか、それとも文字コードなのか・・・

結局、下記にたどり着いた。
・「〇〇〇_〇〇〇」はダメ
・「〇〇〇-〇〇〇」はOK

その後、「ひょっとしてLaravelが原因?」と思いいたり・・・再調査。

再調査

再調査といってもただのPHPを用意してそこにリクエストヘッダとかを投げて取得って感じ。

▼受け手

<?php
var_export($_POST);
var_export(getallheaders());
var_export($_SERVER);

これだと
・「〇〇〇_〇〇〇」はOK
・「〇〇〇-〇〇〇」はOK
となった。

ひとまずコレでlaravelの「\Request::header()」のトコを「getallheaders()」に差替えて対応完了。
※「getallheaders()」は「apache_request_headers()」が本体だそうだ→「apache_request_headers()」でもOK

めも:getallheaders()

詳しくは調べていないので分からないが「getallheaders()」が使えないサーバもあるそうだ。

▼自前で用意する場合

if (!function_exists('getallheaders')) {
  function getallheaders() {
    $headers = array();
    foreach ($_SERVER as $name => $value) {
      if (substr($name, 0, 5) == 'HTTP_') {
        $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
        //// 「HTTP_」から始まるモノを対象にして、「HTTP_」を削除。「_」を「空白」に変更
        //$tmpName_delHTTP = str_replace('_', ' ', substr($name, 5));
        //
        //// 全部小文字にする
        //$tmpName_lower = strtolower($tmpName);
        //
        //// 文字列の各単語の最初の文字を大文字にする
        //$tmpName_FstChar = ucwords($tmpName_lower);
        //
        //// 「空白」を「_」に戻す
        //$tmpName_Fix = str_replace(' ', '-', $tmpName_FstChar);
        //
        //$headers[$tmpName_Fix] = $value;
      }
    }
    return $headers;
  }
}

再々調査:「_(アンダースコア)」がダメ

その後、色々とあり・・・「HTTPプロトコルのRFC」ってヤツが「_(アンダースコア)」を禁止という情報にたどり着いた。

詳しくは知らない。調べる場合は「nginxプロキシ」あたりがキーワードになるっぽい。

▼ちらっと見かけた情報
・ヘッダで「_(アンダースコア)」を使うのは、OK
・CGIプログラムで使うヘッダに「_(アンダースコア)」は、NG
とか。

「_(アンダースコア)」を使いたい

サーバの設定をいじればOK。
※いじる気は無いので、未調査
※「underscores_in_headers on」あたりで調べる感じでいけそうな気がする