PHP基本編

展開配慮と無害化

1. 演習準備

 これまでの資料では、単純な「データ入力→出力」といった処理を作成してきましたが、ここでは「入力ページ→確認ページ→完了ページ」といった、より一般的なシステムのページ展開を想定したサンプルを検討したいと思います。
 そこでまずは必要なファイルを準備しましょう。[Xamppフォルダ]→[htdocsフォルダ]→[pkpkisoフォルダ]で、ひな形ファイル「hina.html」を[Ctrl]+[c]でコピー。貼り付け[Ctrl]+[v]を3回して下さい(ひな形ファイルが意味不明な人はHTML復習編・ひな形HTMLを確認)。3つ分コピーができるので、それぞれの名前を「kihon05.html」「kihon05a.php」「kihon05b.php」に変更します。そして3つのファイルをテキストエディタ(Terapad等)で開きましょう(TerapadについてはPHP開発環境準備編・テキストエディタを参照)。それぞれを次のように編集します(ここで時間をかけても仕方ないのでコピペでOK)。

  kihon05.html
  

 まずkihon05.htmlは簡単。これまでに何度も見てきたのと同じです。<form>タグによってkihon05a.phpにpostメソッドでonamaeとgoikenという2つのデータを送るという内容です。そしてデータ入力部品として2つの<input type="text">と送信ボタン<input type="submit">、リセットボタン<input type="reset">を設置しています。

SPONSORED LINK

  kihon05a.php
  

 次に2ページ目の「確認ページ」にあたるkihon05a.php。これも問題ないでしょう。postメソッドで送られてきたデータを$_POSTで受け取り$onamaeと$goikenに代入。いずれかの変数が「''」(シングルコーテーション2つ)に等しい、つまり「文字列ナシ(未入力)に等しい」場合に「未入力項目があります」と表示しています。論理和「or」大丈夫ですか?そしてelse以下で「if条件が満たされない場合」に処理する内容を指定しています。ここでは3つのecho文で「こんにちは~さん」「ご意見:~」「以上でよろしいですか?」と表示しています。

  kihon05b.php
  

 最後の「完了ページ」のkihon05b.php。これは簡単。「ありがとうございました」と表示しているだけです。
 作成したらlocalhost経由で表示してみましょう。もちろんXampp起動が必要です(わからない人はPHP開発環境準備編・Xamppの起動Xamppの設定参照)。「http://localhost/phpkiso/kihon05.html」からアクセスしてデータを入力して送信すると「kihon05a.php」に展開してデータが表示されます。データを入力していないとメッセージが出ます。ですがもちろんまだ次のページには進めません。送信ボタンもリンクも作ってません。
 というわけで「kihon05b.php」には、ブラウザのアドレスバーで「http://localhost/phpkiso/kihon05b.php」と直接打ち込んで表示させましょう。「ありがとうございました」と表示されればここではOKです。うまくいかない場合はよく見直しましょう。

  

  

  

SPONSORED LINK


2. データの内部渡し

 準備が終わったらサンプルを改良していきましょう。まずは2ページ目の「確認ページ」から3ページ目の「完了ページ」への展開です。
 データの入力を受け付ける仕組みの場合、一般的には「確認ページ」では入力内容を表示して確認を促し、確認後「完了ページ」に展開した段階で、入力内容がファイルに保存されたり、データベースに格納されたり、実際に処理が行われます。ですので、「確認ページ」から「完了ページ」に展開する際にも入力データを受け渡す必要があります。
 そこで、すでに受け取ったデータを、さらに次のページに受け渡したい場合にどうするか?サンプルを作って確かめましょう。
 「kihon05.html」は修正する必要はありませんのでそのまま。「kihon05a.php」と「kihon05b.php」を編集していきます。

  kihon05a.php(php部分以外は省略)
  

 まず2ページ目の確認ページ「kihon05a.php」。修正したのは後半。「以上でよろしいですか?」と表示した後の行からです。ここでは3ページ目の「kihon05b.php」にデータを送るために、echo文で<form>~</form>タグと<input>タグを出力しています。わかりますか?echo命令で出力される内容を意識しながらよく見て下さい。<form>~</form>と<input>タグの構造が見えてくるはずです。
 最初の<form>タグは、postメソッドで「kihon05b.php」にデータを送るように指定しています。データを受け渡す「完了ページ」を設定しているわけです。
 その次に続く2行はちょっと注目です。<input type="hidden">タグが使われています。覚えていますか?Webページには表示させずに「隠して」データを送る方式です。「隠して」とは言ってもソースを表示すると見えますので情報セキュリティのために役立つものではありませんが、一応ブラウザ上では見えない内部的なデータ渡しの方法です。忘れた人はHTML復習編・入力フォームを確認して下さい。いずれにせよ、この2ページ目の「kihon05a.php」のように、入力されたデータをいったん表示して中継ぎするようなページから次のページにデータを送る際に、<input type="hidden">タグが使われるわけです。
 ところでこの<input type="hidden">タグのあるecho文の書き方は大丈夫ですか?ちょっと拡大して色分けして書くと・・・

echo '<input type="hidden" name="onamae" value="'.$onamae.'">';

 ・・・となっているように、文字列としてのhtmlタグと、送るデータ(この場合は$onamae)を「.」(ピリオド)で結合して、出力する<input>タグを形成していることが分かります。ここでは、<input>タグのvalue属性に、$onamaeの内容が設定される形になっています。「'」(シングルコーテーション)と「"」(ダブルコーテーション)が入り組んでいるのでちょっと複雑に見えますが、「'」はecho文で出力する文字列の範囲を識別するためのもの、「"」はecho命令で出力されるhtmlの一部として見れば区別はつくはずです。
 それから最後に、送信ボタンと終了タグ</form>を出力しています。入力ページではないのでリセットボタンは不要です。

  kihon05b.php(php部分以外は省略)
  

 次は3ページ目の「kihon05b.php」です。2行目から5行目まで追加です。内容的にはOKですよね?postメソッドで送られてきたデータを$_POSTで受け取って$onamaeと$goikenに代入し、「~さん、以下のご意見を承りました。~ありがとうございました」と表示するだけの処理です。

SPONSORED LINK

 作成したらlocalhost経由で表示します。「kihon05.html」からアクセスしてデータを入力して送信すると「kihon05a.php」に展開してデータが表示されます。データを入力していないとメッセージが出ます。さらに送信ボタンをクリックすると「kihon05b.php」に展開し、入力内容が表示されます。以下は「kihon05.html」から展開した後の、確認ページ「kihon05a.php」と完了ページ「kihon05b.php」です。できましたか?うまくいかない場合はよく見直しましょう。

  

  

3. データを消さずに戻る機能

 このようにページが次々に展開されるようになると「戻る」機能があった方が便利です。ここで作ったサンプルの場合は2ページ目の「kihon05a.php」に必要ですよね。「確認ページ」となっているわけですから、確認して修正があれば戻れるようにしておく方が、ユーザーに親切です。
 それではどうやって「戻る」機能を実現するか?<a>タグを使ってhref属性に「kihon05.html」にリンクを張っても「戻る」機能は作れます。でもこの場合は一つ問題があります。そのようにリンクを作ると入力ページに戻った際にデータが消えてしまうんです。なぜそうなるかはHTML復習編・表とリンクにもありますが、リンクで改めてページにジャンプし直しているからです。
 ではどうするか?それはJavascriptの「history.back()」関数を使って実現します。履歴をたどって戻れるようにするわけです。そこで次の<input>タグを「kihon05a.php」に追加してみましょう。ちょうど「リセット」ボタンが表示されている右側に表示すると良さそうです。

  

  

4. 無害化サニタイジング

 突然ちょっとややこしそうなタイトルが登場しました。でも大事なことなので逃げちゃダメです。やり方を見る前に上で作ったサンプルで少し実験をしましょう。

SPONSORED LINK

 ブラウザでlocalhost経由で「kihon05.html」にアクセスし、「お名前」欄に「<font size=7>」と入力し「ご意見」欄には適当にテキストを入れて送信してみて下さい。

  

 どうなりましたか?以下のように「~さん」以後の文字が大きく表示されたと思います。なぜだか気づく人もいるでしょう。そうです、「お名前」欄に入力した「<font size=7>」が、phpプログラムで出力されたために、その後の文字サイズが大きくなったわけです。

  

 「文字が大きくなっただけじゃん」と思うかもしれませんが、これは「ユーザーによってサイトの表示が変更させられた」ことを意味します。つまり「改ざん」です。勝手にプログラムを変更させられてしまう可能性があるわけです。このように、システムの入力欄から何らかのスクリプト(プログラム)を流し込むことによって問題が起きることを「クロスサイトスクリプティング(XSS)」と言ったりしますが、このようなことが起きないよう対策する必要があります。そしてこの対策のことを「サニタイジング」(無害化)と言います。
 方法はいろいろありますが、ここでは最も基本的な「htmlspecialchars命令」を使った方法を確認しましょう。使い方は以下の通りです。

  

 この意味は、変数$hensuに入力された文字データを無害化して$hensuに再度代入する、ということです。「ENT_QUOTES」は、シングルコーテーションとダブルコーテーションを変換するという意味のオマジナイ(こう書くものと覚えておけばOKなもの)です。「Shift_JIS」は文字コード名。別の文字コードの場合は変更します。他には例えば「UTF-8」「EUC-JP」などがあります。
 それでは実際にサンプルで試しましょう。データを受け取り処理する「kihon05a.php」と「kihon05b.php」を以下のように修正しましょう。

  kihon05a.php
  

  kihon05b.php
  

SPONSORED LINK

 修正して[Ctrl]+[s]で上書き保存してlocalhost経由でアクセスして動作確認します。先と同様「kihon05.html」の「お名前」に「<font size=7>」と入力し「ご意見」には適当に入力して送信してみて下さい。以下のようになるはずです。

  

  

 つまり「<font size=7>」として入力されたものが「htmlタグ」としてではなく、単なる文字列として扱われて表示されている、ということです。データ入力を受け付ける処理を作る場合は、忘れずに設定するようにしましょう。



練習問題

 このページで用いたファイルkihon05.htmlとkihon05a.php、kihon05b.phpを使い、以下の課題に取り組みましょう。
  1. kihon05.htmlの「お名前:」の入力欄の下に、「ご住所:」の入力欄を作成し、<input type="text" name="jusyo">として追加しなさい。
  2. そのうえでkihon05a.phpを編集して、入力された住所データを受け取りhtmlspecialchars命令によって無害化して、「こんにちは~さん」の下に「ご住所:~」として住所が表示されるようにしなさい。完成後、「<font size="7">」などのHTMLタグを入力して無害化されていることを確かめよ。
  3. さらにkihon05a.phpを編集して、住所データも<input type="hidden">タグによってkihon05b.phpに内部渡しできるようにし、kihon05b.phpも編集して、住所データを受け取り「(ご住所:~)」と表示されるようにしなさい。
練習問題の出力例

ページのトップへ戻る
SPONSORED LINK