トップページ  > ウェブ制作チュートリアル  > 受け取ったデータを安全な文字列に変換する
【番外編】 第30章 PHPでメール送信フォームを作る

★受け取ったデータを安全な文字列に変換する

受け取ったデータを安全な文字列に変換する

広告

前回までに、ユーザーがフォームから入力した内容を次のページで受け取って画面表示するところまで作成しました。 今回は、ユーザーが入力した内容をプログラム内で利用する際に注意すべき点を確認します。

ユーザーにHTMLタグを入力されたらどうなる?

いま作成しているメール送信フォームのようにユーザーが入力した内容を利用するプログラムでは、 入力されたテキストなどの内容をプログラム内で利用する際には安全面において注意が必要となります。

もし仮にフォーム入力ページのお名前欄に「山田<hr>太郎」と入力すると、次の確認ページでの画面表示はどうなるでしょうか。 実際に入力して試してみましょう。



上図のように画面には水平線が描画されました。 いま作成途中のメールフォームの確認画面では、ユーザーによってHTMLタグなどの特別な文字を入力された場合の対策をしていません。 そのため、意図しないHTMLのhr要素、すなわち水平線が描画されてしまったのです。

HTMLタグを入力される程度ならば、画面のレイアウトが崩れる程度で済みます。 しかし、内部のPHPプログラムが偶然に実行されてしまうようなスクリプトを送信されないとも限りません。 ユーザーによって入力された内容はプログラム内部でそのまま利用するのではなく、 必ずプログラムやブラウザ表示に影響しないように変換してやる必要があるのです。

ユーザーの入力内容を安全な文字列に変換する

前のページから受け取ったデータを安全な文字列に変換する対策をします。 confirm.phpを開いて、下記のように書き換えてください。

サンプルソース:confirm.php
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>入力内容の確認|メール送信フォーム</title> </head> <body> <?php /* データの受け取り */ $namae = $_POST["namae"]; //お名前 $mailaddress = $_POST["mailaddress"]; //メールアドレス $naiyou = $_POST["naiyou"]; //お問合せ内容 //危険な文字列を入力された場合にそのまま利用しない対策 $namae = htmlspecialchars($namae, ENT_QUOTES); $mailaddress = htmlspecialchars($mailaddress, ENT_QUOTES); $naiyou = htmlspecialchars($naiyou, ENT_QUOTES); /* 入力内容の確認 */ echo '<h3>入力内容を確認します</h3>'; echo '<dl>'; echo '<dt>【お名前】</dt><dd>'.$namae.'</dd>'; echo '<dt>【メールアドレス】</dt><dd>'.$mailaddress.'</dd>'; echo '<dt>【お問合せ内容】</dt><dd>'.nl2br($naiyou).'</dd>'; echo '</dl>'; ?> </body> </html>

入力が完了したら、confirm.phpを上書き保存して、もう一度表示確認してみてください。



今度はHTMLタグを入力しても、ウェブページの描画に影響を与えていません。 HTMLタグを入力してもそのまま文字列として表示されるようになりました。

記述したソース内容を確認しよう

htmlspecialchars()関数を掛ける

今回追加したソースをあらためて確認してみましょう。

サンプルソース:confirm.phpの抜粋
//危険な文字列を入力された場合にそのまま利用しない対策 $namae = htmlspecialchars($namae, ENT_QUOTES); $mailaddress = htmlspecialchars($mailaddress, ENT_QUOTES); $naiyou = htmlspecialchars($naiyou, ENT_QUOTES);

PHPのhtmlspecialchars()関数は、HTMLとして認識されてしまう特別な文字を無効化してくれる関数です。 例えば、 < は &lt; に、 > は &gt; に、 " は &quot; に、それぞれ変換されます。

シングルクォーテーション( ' )もプログラム内でそのまま利用していると問題が起きる可能性がある危険な文字です。

htmlspecialchars($namae)

上記の書式では、シングルクォーテーション( ' )は変換されませんが、下記の書式にするとシングルクォーテーション( ' )は&#039;に変換されます。

htmlspecialchars($namae, ENT_QUOTES);

セキュリティ対策はイレギュラーな行動をするユーザーへの対策です。 htmlspecialchars()関数を掛ければセキュリティ対策が万全ということではありませんが、 ひとまずHTMLタグなど入力されてしまった場合の基本対策だけでもしておきましょう。

余分なバックスラッシュ( \ )がつく

PHPでシングルクォーテーション( ' )やダブルクォーテーション( " )が含まれた文字列を受け渡す際、 自動的にバックスラッシュ( \ )が付けられてエスケープされてしまう場合と、 エスケープされない場合とがあります。

これは利用しているサーバーの設定によります。 シングルクォーテーション( ' )やダブルクォーテーション( " )はPHPのプログラムに影響を与える可能性のある危険な文字です。 そのため、サーバー側で自動的にエスケープしてしまう設定にしている場合があるです。

この設定は安全対策としてはありがたいのですが、例えば「Let's Go!」と入力した場合にも 「Let\'s Go!」という具合に余分なバックスラッシュ( \ )が入ってしまうため、取り除きたいことがあるかもしれません。

文字列からバックスラッシュ( \ )を取り除くには、ひとつにはサーバーの設定を変更する方法がありますが、 この安全対策を外してしまうということは、それだけイレギュラーな事故が起きる可能性が高まるということでもあります。

PHPには文字列からバックスラッシュ( \ )を取り除くstripslashes()という関数が用意されているので、それを使用する方法もあります。 このレッスンで作成するメール送信フォームではstripslashes()関数は使用しませんが、 そうした関数があることを覚えておくと良いでしょう。

ユーザーの入力した改行を画面上の表示に反映させる

今回の変更では、nl2br()という関数も追加されています。 PHPのnl2br()関数は、テキスト中の改行をHTMLタグの<br />に変換してくれる関数です。

サンプルソース:confirm.phpの抜粋
/* 入力内容の確認 */ echo '<h3>入力内容を確認します</h3>'; echo '<dl>'; echo '<dt>【お名前】</dt><dd>'.$namae.'</dd>'; echo '<dt>【メールアドレス】</dt><dd>'.$mailaddress.'</dd>'; echo '<dt>【お問合せ内容】</dt><dd>'.nl2br($naiyou).'</dd>'; echo '</dl>';

nl2br関数を掛ける前は、ユーザーがお問い合わせ内容の欄で改行しても、確認表示では改行が反映されていませんでした。

それが、nl2br関数を掛けると、確認表示で改行が反映されるようになっています。 些細なことですが、ユーザーとしては入力内容が読みやすくなるように改行を入れた可能性が高いので、 その改行を反映したほうがユーザーの意図に近い表示となるでしょう。

シングルクォーテーションとダブルクォーテーション

PHPで文字列を扱う際には、シングルクォーテーション( ' )、または、ダブルクォーテーション( " )で囲みます。 いま作成しているメール送信フォームのPHPプログラムでは、文字列をシングルクォーテーション( ' )で囲む書き方を基本としています。

なぜ、シングルクォーテーション( ' )で囲む書き方を基本としたかというと、 PHPで出力するHTMLソースは、属性名や属性値などをダブルクォーテーション( " )で囲むことが多いからです。 つまり、「HTMLソース中ではダブルクォーテーション( " )を使用することが多いので、 その外側を囲むPHPソース部分はシングルクォーテーション( ' )を使用したほうが記述がラクかな…」 という程度の判断でそれ以上の意味はありません。

サンプルソース
echo '<div id="header" class="honbun">シングルクォーテーションとダブルクォーテーション</div>';

これは記述方針の問題ですから、シングルクォーテーション( ' )とダブルクォーテーション( " )を逆にして、以下のように記述しても問題ありません。

サンプルソース
echo "<div id='header' class='honbun'>シングルクォーテーションとダブルクォーテーション</div>";

また、出力する文字列に含まれるダブルクォーテーション( " )を、以下のようにバックスラッシュ( \ )でエスケープしてやる方法もあります。

サンプルソース
echo "<div id=\"header\" class=\"honbun\">シングルクォーテーションとダブルクォーテーション</div>";

いずれも誤りではありませんので、自分なりにルールを決めて見やすいソースを記述すれば良いでしょう。

ただし、 PHPではシングルクォーテーション( ' )で囲んだ場合と、ダブルクォーテーション( " )で囲んだ場合とでは挙動が異なる場面があるので注意が必要です。 ダブルクォーテーション( " )で囲んだ場合には、その内側に変数が含まれていれば変数に格納されている内容に置き換えられます。 一方、シングルクォーテーション( ' )で囲んだ場合には、その内側に変数が含まれていてもそのまま文字列として扱われます。

サンプルソース
<?php $name = '山田太郎'; echo "例1:こんにちは、$nameさん\n"; //"~"で囲んだ場合、変数の内容が出力される echo '例2:こんにちは、$nameさん\n'; //'~'で囲んだ場合、変数はそのまま文字列として出力される echo '例3:こんにちは、'.$name.'さん'; //変数の中身を出力するには、変数部分だけ''の外側で指定する ?>

上記のPHPソースの出力結果は以下の通りです。

サンプルの出力結果
例1:こんにちは、山田太郎 さん 例2:こんにちは、$namae さん\n例3:こんにちは、山田太郎 さん
<前へ 目次へ 次へ>
広告
Sponsors
広告
MuuMuu Domain!
ドメイン取るならお名前.com
現役エンジニアのオンライン家庭教師【CodeCamp】
サイトに広告を掲載してお小遣いが稼げる!【A8.net】
Node.jsコース
はじめてのプログラミングコース
▲ページ先頭へ
HTMLクイックリファレンスについて
© HTMQ