見出し画像

コンタクトフォームの作り方【PHP】

※自分用の備忘録です。

PHPでのコンタクトフォームの作り方です。

必要なファイルを用意する

  • contact.php(入力ページ)

  • confirm.php(確認ページ)

  • complete.php(完了ページ)

入力ページ(contact.php)

HTML部分

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div class="container">
    <form action="" method="POST" novalidate>
      <h2>お問い合わせ</h2>
      <div>
        <div>
          <label for="inputName">お名前</label>
        </div>
        <div>
          <input type="text" name="name" id="inputName" value="<?php echo htmlspecialchars($post['name']) ?>" required autofocus>
        </div>
        <?php if ($error['name'] === 'blank') : ?>
          <p>※お名前をご記入下さい</p>
        <?php endif; ?>
      </div>
      <div>
        <div>
          <label for="inputEmail">メールアドレス</label>
        </div>
        <div>
          <input type="text" name="email" id="inputEmail" value="<?php echo htmlspecialchars($post['email']) ?>" required>
        </div>
        <?php if ($error['name'] === 'blank') : ?>
          <p>※メールアドレスをご記入下さい</p>
        <?php endif; ?>
        <?php if ($error['email'] === 'email') : ?>
          <p class="error_msg">※メールアドレスを正しくご記入下さい</p>
        <?php endif; ?>
      </div>
      <div>
        <div>
          <label for="inputContent">お問い合わせ内容</label>
        </div>
        <div>
          <textarea type="text" name="contact" id="inputContent" value="" rows="10" required><?php echo htmlspecialchars($post['contact']) ?></textarea>
          <?php if ($error['name'] === 'blank') : ?>
            <p>※内容をご記入下さい</p>
          <?php endif; ?>
        </div>
      </div>
      <div>
        <button type="submit">確認画面へ</button>
      </div>
    </form>
  </div>

</body>

</html>

form内にinputタグやtextareaタグで必要項目を作成し、必要な属性を付与します。

labelタグは必須ではありませんが、操作の際にinputタグやtextareaタグに紐付けされていると便利です。

<label for="inputName">お名前</label>
<input id="inputName">
ラベルのforとinputのidを同じ名前にすることにより、紐付けることができます。

labelの使い方

formタグに必要な属性

  • action

  • method="POST"

  • novalidate

inputタグに必要な属性

  • type「inputの種類を選択」

  • name「phpとの紐付け」

  • id「labelとの紐付け」

  • value「phpから値を出力」

  • required「記述欄が空欄だった時用」

最初に入力したい欄にフォーカスを当てることができる「autofocus」も便利な属性です。

textareaタグはrowsタグで行数を設定できます。

ボタンを押した時の移動先

 <form action="confirm.html" method="POST" novalidate>

ボタンを押した時の移動先はformタグのaction属性で設定をします。

action属性を空にしておくと、エラーがあった時などにそのページに戻って来させることができ、よりシンプルにコンタクトフォームを作ることができます

ボタン自体はform内に作成すれば、formのボタンとして機能します。

ブラウザ側でのエラーの確認処理

<input type="text" name="name" id="inputName" class="form-control" required autofocus>

required属性はHTMLで実装するブラウザでの検証機能の便利な機能です。
しかし、検証機能などで不正に書き換えもできてしまうので、他の処理と併用しましょう。

requiredは親要素であるformタグにnovalidate属性を記述すると無効化できます。
設定し忘れのないようにrequiredはinputタグなどに付与しておき、開発中novalidateを使って無効化しておきましょう。

開発完了後、novalidateを削除しvalidateの有効化を忘れないように注意が必要です。

name属性を記述

<input type="text" name="name" id="inputName" class="form-control" required autofocus>

inputタグに入力された情報をPHPで取得するためにはname属性を使用します。

PHP部分

<?php
session_start();
$error = []; 

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
  if ($post['name'] === '') {
    $error['name'] = 'blank';
  }
  if ($post['email'] === '') {
    $error['email'] = 'blank';
  } 
  if ($post['contact'] === '') {
    $error['contact'] = 'blank';
  }

  if (count($error) === 0) {
    $_SESSION['form'] = $post;
    header('Location: confirm.php');
    exit();
  }
} else {
  if (isset($_SESSION['form'])) {
    $post = $_SESSION['form'];
  }
}
?>

PHPは同じファイル内の上部に「<?php」と「?>」の間に記述をします。

入力が空だった時の処理

<?php
$error = [];

  if ($_POST['name'] === '') {
    $error['name'] = 'blank';
  }
?>

PHP側で$_POST['name']と記述することでinputに書かれたものを取得できます。

if文を使って処理を記述します。

if (条件){処理}

PHPのif文の書き方

($_POST['name'] === '')と書くことでnameが空だったらという意味合いになります。

配列を使って入力が空だった時の処理を記述します。

$変数名 = [キー1 => 値1, キー2 => 値2];

PHPの配列の書き方

$変数名 = [];
$変数名[キー] = 値;

配列に後からキーと値を追加する書き方

入力が空だった時にエラーメッセージを表示

<input type="text" name="name" id="inputName" class="form-control" required autofocus>
<?php if ($error['name'] === 'blank'): ?>
<p>※お名前をご記入下さい</p>
<?php endif; ?>

nameが空っだったった時にendifまでの処理が行われ、「※お名前をご記入下さい」を表示します。

入力のタイミングを調整

<?php
$error = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  if ($_POST['name'] === '') {
    $error['name'] = 'blank';
  }
}
?>

処理を行うタイミングをボタンを押した時に調整するたREQUEST_METHODをif文で記述します。

入力される文字をフィルタリング

<?php
$error = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
  if ($post['name'] === '') {
    $error['name'] = 'blank';
  }
}
?>

入力される文字列にフィルターをかけるため、「filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);」を使用します。
この書き方はシンプルなものになりますが、数字だけ入力された時などの条件も付与できます。

入力されたものを残すため、inputタグにvalueを追加

<input type="text" name="name" id="inputName" class="form-control" value="<?php echo htmlspecialchars($post['name']) ?>" required autofocus>

このままだと送信ボタンを押した際に入力されたものが全てリセットされてしまうため、valueを設定し入力された文字をechoして自動入力させます。

メールアドレスや、内容を入力する欄なども同じように作成をする

<?php
$error = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
  if ($post['name'] === '') {
    $error['name'] = 'blank';
  }
  if ($post['email'] === '') {
    $error['email'] = 'blank';
  }
  if ($post['contact'] === '') {
    $error['contact'] = 'blank';
  }
}
?>
<?php if ($error['name'] === 'blank') : ?>
  <p>※メールアドレスをご記入下さい</p>
<?php endif; ?>
<?php if ($error['name'] === 'blank') : ?>
  <p>※内容をご記入下さい</p>
<?php endif; ?>
<input type="email" name="email" id="inputEmail" value="<?php echo htmlspecialchars($post['email']) ?>" required>
<textarea name="contact" id="inputContent" rows="10" class="form-control" required><?php echo htmlspecialchars($post['contact']) ?></textarea>

内容を入力する欄でtextareaタグを使用する場合は、value属性ではなくタグとタグの間に<?php echo htmlspecialchars($post['contact']) ?>と記述します。

メールアドレスのフィルタリング

if ($post['email'] === '') {
    $error['email'] = 'blank';
  } else if (!filter_var($post['email'], FILTER_VALIDATE_EMAIL)) {
    $error['email'] = 'email';
  }
<?php if ($error['email'] === 'blank') : ?>
  <p class="error_msg">※メールアドレスをご記入下さい</p>
<?php endif; ?>
<?php if ($error['email'] === 'email') : ?>
  <p class="error_msg">※メールアドレスを正しくご記入下さい</p>
<?php endif; ?>

メールアドレスのフィルタリングは「!filter_var($post['email'], FILTER_VALIDATE_EMAIL)」と記述することでメールの型を判別してくれます。

if文で専用のエラーメッセージを用意し、input欄に入力された文字列によって違うエラーメッセージを使い分けることができます。

エラーがなかった場合、確認ページへ移動

session_start();  
//セッション関数を使えるようにするために記述
if (count($error) === 0) {
  $_SESSION['form'] = $post;
  header('Location: confirm.php');
  exit();
}

セッション変数を使って入力されたデータ情報を受け渡します。

header('Location: ファイルのパスやURL');

PHPの画面遷移の書き方

header関数はあらゆる出力よりも先に呼び出すというルールがあります。
<html>より先に記述をしましょう。

確認画面(confirm.php)

HTML部分

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <form action="" method="POST">
    <p>確認画面</p>
    <p>お名前</p>
    <p><?php echo htmlspecialchars($post['name']) ?></p>
    <p>メールアドレス</p>
    <p><?php echo htmlspecialchars($post['email']) ?></p>
    <p>お問い合わせ内容</p>
    <p><?php echo nl2br(htmlspecialchars($post['contact'])) ?></p>
    <div>
      <a href="contact.php">戻る</a>
    </div>
    <button type="submit">送信する</button>
  </form>
</body>

</html>

PHP部分

<?php
session_start();

if (!isset($_SESSION['form'])) {
  header('Location: contact.php');
  exit();
} else {
  $post = $_SESSION['form'];
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $to = 'メールアドレス@example.com';
  $from = $post['email'];
  $subject = 'お問い合わせが届きました';
  $body = <<<EOT
名前: {$post['name']}
メールアドレス: {$post['email']}
内容:
{$post['contact']}
EOT;
  mb_send_mail($to, $subject, $body, "From: {$from}");
  //セッションの削除
  unset($_SESSION['form']);
  header('Location: complete.php');
  exit();
}
?>

セッション変数を使用しデータを受け取る

<?php
session_start();

$post = $_SESSION['form'];

?>

これで入力画面の内容を取得できます。

文字の出力

<?php echo htmlspecialchars($post['name']) ?>

<?php echo htmlspecialchars($post['email']) ?>

<?php echo nl2br(htmlspecialchars($post['contact'])) ?>

出力したい場所にecho htmlspecialcharsを記述します。

お問い合わせを書く欄などの改行が入る可能性がある場所は、nl2br()と記述し改行をbrタグに変換します。

改行を正しく表示する方法はpreタグを使う方法もあります。

<pre><?php echo htmlspecialchars($post['contact']) ?></pre>

入力画面のアクセス以外は戻す

if (!isset($_SESSION['form'])) {
  header('Location: contact.php');
  exit();
} else {
  $post = $_SESSION['form'];
}

直接URLを入力するなどしてconritm.phpにアクセスできないようにif文で設定をします。

戻るボタンの設定

<a href="contact.php">戻る</a>

ボタン自体はaタグを使ってパスを指定します。

戻るボタンを押した際に入力されたデータも入力された状態にする

contact.php

else {
  if (isset($_SESSION['form'])) {
    $post = $_SESSION['form'];
  }
}

このままでは戻った時に入力したものが消えてしまうため、自動に入力されるように設定をします。

戻った際に入力される欄は「<?php echo htmlspecialchars($post['contact']) ?>」ですで設定しているので再度設定する必要はありません。

メールの送信の設定

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $to = 'メールアドレス@example.com';
  $from = $post['email'];
  $subject = 'お問い合わせが届きました';
  $body = <<<EOT
名前: {$post['name']}
メールアドレス: {$post['email']}
内容:
{$post['contact']}
EOT;
}

ヒアドキュメントで本文を設定

<<<開始ID
  [本文]
  [本文]
  [本文]
終了ID;
//終了IDは字下げ禁止

ヒアドキュメントの書き方

ヒアドキュメント内では改行、タブ文字、クオート記号などがそのまま使うことができ、変数は展開されます。

メールの送信

mb_send_mail($to, $subject, $body, "From: {$from}");

mb_send_mail($to, $subject, $message);

$to 送信先のメールアドレス
$subject メールの件名
$message メールの本文
その他任意の変数が送信できます。

メール送信の書き方

セッションの削除

  unset($_SESSION['form']);
  header('Location: complete.php');
  exit();

最後にセンションを削除し完了画面を表示します。

unset($セッション変数);

セッションの削除

完了画面(complete.php)

HTML部分

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <p>お問い合わせありがとうございました</p>
  <div>
    <a href="contact.php">トップに戻る</a>
  </div>
  
</body>
</html>

完了画面はお礼のメッセージとトップへのリンクを作るぐらいで特にPHPは使いません。

※メールは実際のサーバーにアップをしないと送信できません。

※仮想サーバーとメールアドレスの設定によっては、アップロードをしなくても送信可能です。

サンプルファイル

GitHub

※こちらのコードは勉強用のサンプルです。
実際に運用する場合はセキュリティにご注意ください。

この記事が気に入ったらサポートをしてみませんか?