プログラミング

PHP の POST を理解する

POST が分からなくて困った

こんにちは!早いものでもう10月中旬になりました。実はハロウィンが誕生日です…

自分が小さい時はハロウィンなんてあまり知られてなかったんですけど、今や誰もが知るイベント?になってちょっとビックリです。

さて、そんなことはどうでもいいとして、最近実務で POST が関わる実装でめちゃくちゃ苦しんでしまって、

「 POST トハ…??」

「 PHP ゼンゼン理解してないんちゃう?」ガタガタ……

となってしまったので自分の理解をちゃんと深めたいと思い。。

今回は、

PHP の POST を理解する

と題して PHP の POST についてまとめてみようと思います。

前回ブログはこちらから↓

POST とは

HTTP メソッドの一種

POST とは、クライアントからサーバにデータを要求する HTTP メソッドの一種で、HTTP メソッドはたくさんあるけど、だいたい「 POST 」か「 GET 」が使われることが多い。

(他にも「 PUT 」とか「 DELETE 」メソッドがあるらしい…調べて初めて知ったし、使ったことない…)

$_POST を使ってアクセスできる

POST 情報は、PHP が元々用意されている「 $_POST 」変数を使って取得することができる。「 $_POST 」は PHP ファイル内のどこからでもアクセスできる「スーパーグローバル変数」である。

スコープを意識せずに「 $_POST 」と書くだけで、どこからでも参照できますよってことですね!

どうやって POST 送信するの?

HTML の form タグ内で「 method=”POST” 」として、「 action 属性 」に POST 送信先の URL を記載した場合に、「 submit 」をクリックすると、サーバに情報が送信される。

具体的には例えば、form タグ内に「 <input type=”text” name=”name” value=””>」というフォームが設置されている場合、そのフォームに入力された値は「 $_POST[‘name”] 」にアクセスすれば参照できる。

POST は連想配列である

POSTって連想配列なんですね。。。

$_POST の正体は「要素名 => 値」の連想配列なので、個々の要素値にアクセスするには$_POST[‘要素名’]のように記述します。

独習PHP

なるほど、この POST の正体を知っていればなぜ「 $_POST[‘name’] 」とかって書くのか理解できるな…

POST 送信の特徴

大まかにこんな感じ。

  • ・情報が見えない( GET だと URL より見えてしまう)
  • ・データ量を気にしなくていい( GET だと送信データ量に制限がある)
  • ・( URL につかないから)ブックマークはできない

個人情報や他人に見られたくない( URL にのっけたくない)データの送信に使われることが多い。

きちんとエスケープ処理をしよう

POST でデータを送信する場合は、セキュリティの観点からエスケープ処理をする必要があります。エスケープ処理には「 htmlspecialchars 」関数を使用する。

「 < 」とか HTML で使用するタグが入力された場合に、HTML としてではなく、きちんと文字列として出力されるようにするってことらしいです。

実際にフォームを作って POST 送信してみる

上記を踏まえて、実際にフォームを作って POST 送信してみます。

わかりやすいように POST 送信先は自分自身として、「送信する( submit )」ボタンを押すとフォームの下部に入力値が出力される、という内容で実装してみます。

form に action 属性を指定しない場合は自身に POST します

ソースコード

動くサンプルはコチラ

// POST データを格納する変数を初期化
$name     = '';
$age      = '';
$favorite = '';
$postData = '';

// エスケープ処理
function e(string $str, string $charset = 'UTF-8'): string {
  return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, $charset);
}

// POST データが存在する場合、入力値を変数に格納する
if(
  !empty($_POST['name']) &&
  !empty($_POST['age']) &&
  !empty($_POST['favorite']) 
){
  $name     = e($_POST['name']);
  $age      = e($_POST['age']);
  $favorite = e($_POST['favorite']);
  // ブラウザに出力させる文字列
  $postData = $name.'さんは'.$age.'歳で、好きな食べ物は'.$favorite.'です!';
}
<body>
  <!-- 自分自身に POST する -->
  <form method="POST">
    <table>
      <tbody>
        <tr>
          <th><label for="name">お名前</label></th>
          <td><input type="text" name="name" id="name" value=""></td>
        </tr>
        <tr>
          <th><label for="age">年齢</label></th>
          <td><input type="text" name="age" id="age" value=""></td>
        </tr>
        <tr>
          <th><label for="favorite">好きな食べ物</label></th>
          <td>
            <select name="favorite" id="favorite">
              <option value="お寿司">選択してください</option>
              <option value="お寿司">お寿司</option>
              <option value="焼肉">焼肉</option>
              <option value="ラーメン">ラーメン</option>
              <option value="そば">そば</option>
            </select>
          </td>
        </tr>
        <tr>
          <th></th>
          <td><input type="submit" value="送信する"></td>
        </tr>
      </tbody>
    </table>
  </form>
  <div class="post_data">
    入力結果:<?=$postData?>
  </div>
</body>

上記のフォームに値を入力して「送信する」ボタンを押すと、下記のように POST データが取得できました!

今回は各フォームに空文字を許容したくなかったので「 !empty 」を使いましたが、空文字を許容するなら「 isset 」がいいのかな?と思いました。(自信がない)

エスケープ処理

上記ではエスケープ処理用の関数を用意しています。

今回のようにフォームの量が少ない場合はいいんですが、多い場合毎回「 htmlspecialchars 〜 」とかやってたら面倒ですからね。いいこと知りました。

エスケープ処理用関数

function e(string $str, string $charset = ‘UTF-8’): string {
return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, $charset);
}

独習 PHP

けど「 e 」って略しすぎな気が…けど esc じゃ分かりづらいし、escape じゃ長いか。。てことで結局「 e 」!w

ちなみに「独習PHP」 は分かりやすくておすすめです。「JavaScript 本格入門」も良かったので、やはり山田先生の著書は分かりやすいな〜と思っています。

POST が連想配列である証

上記で POST は連想配列であると記載しましたが、試しに上記のコードで「 var_dump($_POST) 」して POST に何が入っているかブラウザに出力してみました。

結果↓

配列でした!!!

当たり前っちゃそうだけど…今まで理解してなかった(小声

まとめ

いかがだったでしょうか。

PHP を学び始めると初期の段階で POST の存在を知りますが、意外にも(?)知ってるつもりで知らなかったことがたくさんあって、また1つ勉強になったなーと思いました。

プログラミングは、本当に難しいですね…

めげずにがんばりましょう。?

次回は(自戒として) POST 絡みで実務でドン詰まりした内容を書こうかな、と思っています。

ここまでお読みいただき、ありがとうございました!