【PHP技術者認定試験問題】リクエスト情報、メールフォーム

スーパーグローバル変数

  • どのスコープでも有効で無常記念でアクセス可能
  • global命令不要

$_POST

<form method="POST">タグでフォームから送信されたデータをポストデータといいます。

$_GET

$_GET … クエリ情報

クエリ情報とはURLの末尾「~?」以降の「キー名=値」でセットされる情報です。

$_SERVER

リクエスト情報やサーバー変数を示します。

ヘッダー情報

PHPでメールフォームを作成

コード内容

  • phpinfo.php
  • contactform.php

phpinfo.php

phpinfo()はPHPの情報を確認でき、PHPが動いている環境か確認できます。

<?php
phpinfo();
?>

contactform.php

<?php
  session_start();

  $mode = 'input';
  $errmessage = array();

  if( isset($_POST['back']) 
  // backという配列のキーがそもそも存在しているか
  // Noticeという注意文が出てしまう

  && $_POST['back'] ){
  // 空ではないか

  // if( $_POST['back']) {
    
  } else if( isset($_POST['confirm']) && $_POST['confirm'] ) {
  // 確認画面

    // 名前のバリデーション(入力チェック)
    if( !$_POST['fullname'] ) {
	    $errmessage[] = "名前を入力してください";
    } else if( mb_strlen($_POST['fullname']) > 100 ){
	    $errmessage[] = "名前は100文字以内にしてください";
    }
	  $_SESSION['fullname'] = htmlspecialchars($_POST['fullname'], ENT_QUOTES);
    // サニタイズ(無害化)

    // メールのバリデーション
    if( !$_POST['email'] ) {
      $errmessage[] = "Eメールを入力してください";
    } else if( mb_strlen($_POST['email']) > 200 ){
      $errmessage[] = "Eメールは200文字以内にしてください";
    } else if( !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ){
      $errmessage[] = "メールアドレスが不正です";
    }
    $_SESSION['email'] = htmlspecialchars($_POST['email'], ENT_QUOTES);

    // お問い合わせ内容のバリデーション
    if( !$_POST['message'] ){
		  $errmessage[] = "お問い合わせ内容を入力してください";
	  } else if( mb_strlen($_POST['message']) > 500 ){
		  $errmessage[] = "お問い合わせ内容は500文字以内にしてください";
	  }
	  $_SESSION['message'] = htmlspecialchars($_POST['message'], ENT_QUOTES);

    if( $errmessage ){
	    $mode = 'input';
    } else {
	    $mode = 'confirm';
    }

  } else if( isset($_POST['send']) && $_POST ) {
    $message = "お問い合わせを受け付けました。\r\n"
              . "名前: " . $_SESSION['fullname'] . "\r\n"
              . "email: " . $_SESSION['email'] . "\r\n"
              . "お問い合わせ内容:\r\n"
              . preg_replace("/\r\n|\r|\n/", "\r\n", $_SESSION['message']);
	  mail($_SESSION['email'],'お問い合わせありがとうございます',$message);
    mail('xx@gmail.com','お問い合わせありがとうございます',$message);
    $_SESSION = array();

    $mode = 'send';

  } else {
    $_SESSION['fullname'] = "";
    $_SESSION['email']    = "";
    $_SESSION['message']  = "";
  }
?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>お問い合わせフォーム</title>
</head>
<body>

  <?php if( $mode == 'input' ) { ?>
    <!-- 入力画面 -->
    <h2>入力画面</h2><br>
    <?php
    if( $errmessage ){
      echo '<div style="color: red;">';
      echo implode('<br>', $errmessage );
      echo '</div>';
    }
    ?>
    <form action="./contactform.php" method="post">
      name<input type="text" name="fullname" value="<?php echo $_SESSION['fullname'] ?>"><br>
      email<input type="email" name="email" value="<?php echo $_SESSION['email'] ?>"><br>
      お問い合わせ内容<br>
      <textarea name="message" id="" cols="30" rows="10">
        <?php echo $_SESSION['message']; ?>
      </textarea><br>
      <input type="submit" name="confirm" value="確認">
    </form>

  <?php } else if( $mode == 'confirm' ){ ?>
    <!-- 確認画面 -->
    <h2>確認画面</h2><br>
    <form action="./contactform.php" method="post">
      name  <?php echo $_SESSION['fullname']; ?><br>
      email <?php echo $_SESSION['email']; ?><br>
      お問い合わせ内容 <br>
      <?php echo nl2br($_SESSION['message']); ?><br>
      <input type="submit" name="back" value="戻る" />
      <input type="submit" name="send" value="送信" />
    </form>
    
  <?php } else { ?>
    <!-- 完了画面 -->
    <h2>送信完了画面</h2><br>
    送信しました。お問い合わせありがとうございました。<br>
  <?php } ?>
 
  <?php
  print_r($_POST );
  ?>
  
</body>
</html>
https://siennahare23.sakura.ne.jp/hinkon/contactform.php

メールフォームのセキュリティについて

クロスサイトスクリプティング対策

htmlspecialcharsという関数を使いエスケープ処理を行います。

スクラッチ以外の利用

実際はWordPressのプラグインやメールフォームのライブラリ(PHPMailer、Laravel)を使用するのが鉄板で無難です。

完全なセキュリティは難しい

セキュリティを十分に考慮されたシステムには、それなりにコストがかかります。

制作しているサイトが、相応の重要なデータを扱っているかを考える必要があります。

【PHP技術者認定試験問題】リクエスト情報

リクエスト情報を取得、操作するためのスーパーグローバル変数 8
$_POSTPOST形式で渡された情報
$_GETクエリ情報経由で渡された情報
$_FILESアップロードされたファイルに関する情報
$_SERVERリクエストヘッダー、またはサーバー固有の変数情報
$_ENVサーバー側で定義された環境変数
$_COOKIEクッキー経由で渡された情報
$_SESSIONセッション経由で渡された情報
$_REQUEST$_GET、$_POST、$_COOKIEの値をまとめて管理
ユーザーからの入力値をブラウザーに表示させる場合の注意点

htmlspecialchars()関数でエスケープすることで、クロスサイトスクリプティング攻撃を防ぎます

主なサーバー変数 7
$_SERVER[‘PHP_SELF’]Webサーバに要求するURL
$_SERVER[‘SERVER_NAME’]PHPは実行されているWebサーバの名前
$_SERVER[‘SERVER_ADDR’]IPアドレス
$_SERVER[‘REQUEST_METHOD’]リクエストのメソッド名
$_SERVER[‘REMOTE_ADDR’]ユーザの IP アドレス
$_SERVER[‘REMOTE_HOST’]現在のページにアクセスしているホストの名前
$_SERVER[‘QUERY_STRING’]検索引数
・名前「name」、値「value」有効期限30日後のクッキーを発行してください
・クッキーを即座に破棄してください
setcookie('name', 'value', time() + 60 * 60 * 24 * 30);
setcookie('name', 'value', time() - 3600);
クッキーを定義する関数は
setcookie(name, value, expire, path, domain, secure, httponly)

1.name … クッキーの名前
2.value … クッキーの値
3.expire … 有効期限
4.path … URLのパス
5.domain … 有効なドメイン
6.secure … secure属性(HTTPS通信時のみ許可)
7.httponly … httponly属性(JavaScriptによるクッキーの操作を防ぐ)