Chapter08 独自関数とメール送信

概要と目標 メールフォームを、
作れるようになろう。

独自関数と、PHPを使ったメールの送信方法を学習し、
メールフォームに必要なページを作成しよう。

今回のゴール

RERUN

独自関数 何度も使う処理を登録し、
いつでも使えるようにする。

関数は、自分で作ることも出来る。何度も使う処理は関数として登録しておくことで、
いつでも呼び出しができるようになる。

独自関数の登録
function 関数名(引数) {
  // ここに関数として登録する処理を記述

  return 戻り値;
      省略可
}

*.引数を複数必要とする場合は、「,(半角カンマ)」で区切って指定する。

引数はPHPマニュアルを参照

独自関数の呼び出し
関数名(引数)

三角形の面積を求める
独自関数を作ってみよう。

  1. 「chapter08」 › 「function」フォルダ内の「index.php」をテキストエディタで開く
  2. 冒頭に、三角形の面積を出力する独自関数を作成
chapter08/function/index.php
<?php
  // 関数の登録
  function  area_of_triangle($base, $height) {
    // 関数として登録する処理
    $result = $base * $height / 2;
    echo $result;
  }
?>
  1. h1要素の下で、三角形の面積を出力する独自関数を呼び出す
chapter08/function/index.php
<p>底辺が 6cm 、高さが 4cm の三角形の面積は、<?php area_of_triangle(6, 4); ?>cm<sup>2</sup>です。</p>
  1. 上書き保存
  2. ブラウザで「chapter08」 › 「function」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/chapter08/function/
ブラウザでの表示例

RERUN

戻り値を設定してみる

関数を登録するブロック内で、echo をすると必ず画面に出力してします。
時には、変数に代入したり、if文の条件式に使いたいときもある。
そういった時は、戻り値を設定する。

  1. 「chapter08」 › 「function」フォルダ内の「index.php」をテキストエディタで開く
  2. functionのブロックの中にある、echoをコメントにし、戻り値を設定する
chapter08/function/index.php
<php
  // 関数の登録
  function  area_of_triangle($base, $height) {
    // 関数として登録する処理
    $result = $base * $height / 2;
    // echo $result;
    return $result;
  }
?>
  1. p要素のarea_of_triangle()echoで出力したり、 if文の条件式にarea_of_triangle()を利用してみる
chapter08/function/index.php
<p>底辺が 6cm 、高さが 4cm の三角形の面積は、<?php echo area_of_triangle(6, 4); ?>cm<sup>2</sup>です。</p>

<?php if ( area_of_triangle(6, 4) >= 10 ) : ?>
  <p>面積が、10cm<sup>2</sup>以上の三角形です。</p>
<?php else : ?>
  <p>面積が、10cm<sup>2</sup>より小さいの三角形です。</p>
<?php endif; ?>
  1. 上書き保存
  2. ブラウザで「chapter08」 › 「function」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/chapter08/function/
ブラウザでの表示例

RERUN

メールの送信 メールの送信は、文字化けとの戦い。

PHPを使ってメールを送信するには、mb_send_mail関数を用いる。
ただし、事前に言語や文字コードの設定を行わなければ、文字化けする可能性がある。
また、XAMPPやMAMPなどでメールを送信する場合は、メールサーバが別途必要となる。

mb_send_mail関数 ・・・ 日本語のメールを送信する関数
mb_send_mail(送信先, 件名, 本文, 送り主などのヘッダ情報)

送り主などのヘッダ情報 … 送り主は、"From: 送り主名<メールアドレス>" の形式で指定
戻り値… ture(送信成功) / false(送信失敗)

詳細はPHPマニュアルを参照

上記の mb_send_mail関数を用いればメールは送信できる。
ただし、これだけでは、日本語が、文字化けする可能性がある。
その為、mb_language関数を使って言語を設定したり、
mb_internal_encoding関数を使って、文字コードを設定したりする必要がある。
さらには、送り主名は、メールヘッダの形式に合わせる必要があるため、
mb_encode_mimeheader関数で、変換する必要がある。

メールを送信してみよう。

  1. 「chapter08」 › 「send-mail」フォルダ内の「index.html」をテキストエディタで開く
  2. h1要素の下に、入力フォームを作成
chapter08/send-mail/index.html
<form action="receive.php" method="post">
  <dl>
    <dt><label for="email">送信先</label></dt>
    <dd>
      <input type="text" name="email" id="email">
    </dd>
  </dl>
  <p><input type="submit" value="送信"></p>
</form>
  1. 上書き保存
  2. 「chapter08」 › 「send-mail」フォルダ内の「receive.php」をテキストエディタで開く
  3. ファイルの冒頭で、日本語の設定を行う
mb_language関数 ・・・ 現在の言語の設定あるいは取得する関数
mb_language(言語)
            省略可

mb_send_mail関数はこの設定を利用してエンコードする。

詳細はPHPマニュアルを参照

mb_internal_encoding関数 ・・・ 文字コードの設定あるいは取得する関数
mb_internal_encoding(文字コード)
                       省略可

詳細はPHPマニュアルを参照

chapter08/send-mail/receive.php
<?php
  // 日本語の設定
  mb_language('ja');
  mb_internal_encoding('UTF-8');
?>
  1. ?>の手前に、メールアドレスの入力チェックを追加
    メールアドレスが空白なら、入力フォームにリダイレクト
chapter08/send-mail/receive.php
<?php
  // 日本語の設定
  mb_language('ja');
  mb_internal_encoding('UTF-8');

  // メールアドレスが空なら、入力フォームにリダイレクト
  if ( $_POST['email'] == '' ) {
      header('Location: ./');
      exit();
  }
?>
  1. ?>の手前に、mb_send_mail()関数に必要な情報を変数に代入する処理を追加
    送り主の名前は、mb_encode_mimeheader()でエンコードする
mb_encode_mimeheader関数 ・・・ MIMEヘッダの文字列をエンコードする関数
mb_encode_mimeheader(エンコードする文字列, 文字コード)
                                         省略可

詳細はPHPマニュアルを参照

chapter08/send-mail/receive.php
<?php
  // 日本語の設定
  mb_language('ja');
  mb_internal_encoding('UTF-8');

  // メールアドレスが空なら、入力フォームにリダイレクト
  if ( $_POST['email'] == '' ) {
      header('Location: ./');
      exit();
  }

  // 値を変数に格納
  $to = $_POST['email'];
  $subject = 'PHPからメール送信テスト';
  $message = 'これはPHPから自動送信されたメールです。';
  $from = mb_encode_mimeheader('ダミー'). '<noreply@dummy.com>';
?>
  1. ?>の手前に、mb_send_mail()関数でメールを送信する処理を追加
    送信が成功したか失敗したかを判別るため、戻り値を変数に受け取っておく
chapter08/send-mail/receive.php
<?php
  // 日本語の設定
  mb_language('ja');
  mb_internal_encoding('UTF-8');

  // メールアドレスが空なら、入力フォームにリダイレクト
  if ( $_POST['email'] == '' ) {
      header('Location: ./');
      exit();
  }

  // 値を変数に格納
  $to = $_POST['email'];
  $subject = 'PHPからメール送信テスト';
  $message = 'これはPHPから自動送信されたメールです。';
  $from = mb_encode_mimeheader('ダミー'). '<noreply@dummy.com>';

  // メールの送信
  $resulut = mb_send_mail($to, $subject, $message, 'From: '. $from);
?>
  1. ?>の手前に、メール送信に成功した時とっ失敗した時で処理を分けるコードを追加
chapter08/send-mail/receive.php
<?php
  // 日本語の設定
  mb_language('ja');
  mb_internal_encoding('UTF-8');

  // メールアドレスが空なら、入力フォームにリダイレクト
  if ( $_POST['email'] == '' ) {
      header('Location: ./');
      exit();
  }

  // 値を変数に格納
  $to = $_POST['email'];
  $subject = 'PHPからメール送信テスト';
  $message = 'これはPHPから自動送信されたメールです。';
  $from = mb_encode_mimeheader('ダミー'). '<noreply@dummy.com>';

  // メールの送信
  $resulut = mb_send_mail($to, $subject, $message, 'From: '. $from);
  if ($resulut) {
    // 送信成功
    $msg = '送信成功';
  } else {
    // 送信失敗
    $msg = '送信失敗';
  }
?>
  1. h1要素の下にメッセージを出力するPHPを追記
chapter08/send-mail/receive.php
<p><?php echo htmlspecialchars($msg, ENT_QUOTES, 'UTF-8'); ?></p>
  1. 上書き保存
  2. ブラウザで「chapter08」 › 「send-mail」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/chapter08/send-mail/
  3. 自分が受信できるメールアドレスを入力し送信する
ブラウザでの表示例

RERUN

メールヘッダ・インジェクション
お問い合わせフォームなどのメール送信時に、メールヘッダを不正に操作し、迷惑メール本来の宛先以外にメールを送信したり、メールの内容を改ざんしたりする攻撃。
  • メールの宛先(To,Cc,Bcc)や件名(Subject)などのメールヘッダーを固定して、メールヘッダーに外部からの入力をさせない
  • 入力値の全ての改行コードを削除する
などの対策を行う。

お問い合わせフォーム セッションを使った、
メールフォームを作ってみる。

お問い合わせフォームはシンプルだが様々な仕様がある。
今回は、セッションを使って、処理ごとにページを分けた仕様で開発する。

お問い合わせフォームの仕様
注意点
今回作成するお問い合わせフォームは、今まで学習した内容を組み合わせて、できるだけシンプルにメールフォームとして機能させることに焦点を置いています。従って、セキュリティへの対策などは別途考察する必要があります。

入力フォームの作成 まずは、必要な入力フォームを作成する。

ユーザーから取得したい項目のフォームを用意しよう。

入力フォームを作成しよう。

  1. 「mail-form」フォルダ内の「index.php」をテキストエディタで開く
  2. h1要素の下に、入力フォームを作成
mail-form/index.php
<form action="set.php" method="post">
  <dl>
    <dt><label for="name">お名前</label></dt>
    <dd>
      <input type="text" name="name" id="name">
    </dd>
    <dt><label for="email">メールアドレス</label></dt>
    <dd>
      <input type="text" name="email" id="email">
    </dd>
    <dt><label for="message">お問い合わせ内容</label></dt>
    <dd>
      <textarea name="message" id="message" rows="8" cols="50"></textarea>
    </dd>
  </dl>
  <p><input type="submit" value="入力確認へ"></p>
</form>
  1. 上書き保存
  2. ブラウザで「mail-form」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/mail-form/
ブラウザでの表示例

RERUN

入力確認ページの作成 入力確認画面のHTMLを作成。

入力確認画面のHTML部分を作成する。

入力確認画面を作成しよう。

  1. 「mail-form」フォルダ内の「conf.php」をテキストエディタで開く
  2. h1要素の下に、入力内容を表示する為のHTMLを部分を記述
mail-form/conf.php
<dl>
  <dt>お名前</dt>
  <dd>

  </dd>
  <dt>メールアドレス</dt>
  <dd>

  </dd>
  <dt>お問い合わせ内容</dt>
  <dd>

  </dd>
</dl>

<ul>
  <li><a href="./">入力フォームへ</a></li>
  <li><a href="send.php">送信</a></li>
</ul>
  1. 上書き保存
  2. ブラウザで「mail-form」フォルダ内の「conf.php」にアクセス
    http://localhost/php-lessons/mail-form/conf.php
ブラウザでの表示例

RERUN

送信完了ページの作成 送信に成功した時に表示するページ。

送信に成功した後に表示するページを作成する。

送信完了ページを作成しよう。

  1. 「mail-form」フォルダ内の「thanks.html」をテキストエディタで開く
  2. h1要素の下に、送信完了ページのHTMLを記述
mail-form/thanks.html
<p>送信完了しました。</p>

<p><a href="./">入力フォームに戻る</a></p>
  1. 上書き保存
  2. ブラウザで › 「mail-form」フォルダ内の「thanks.html」にアクセス
    http://localhost/php-lessons/mail-form/thanks.html
ブラウザでの表示例

RERUN

送信失敗ページの作成 送信に失敗した時に表示するページ。

送信に失敗した後に表示するページを作成する。

送信失敗ページを作成しよう。

  1. 「mail-form」フォルダ内に「error.html」をテキストエディタで開く
  2. h1要素の下に、送信エラーページのHTMLを記述
mail-form/error.html
<p>送信に失敗しました。</p>

<p><a href="./">入力フォームに戻る</a></p>
  1. 上書き保存
  2. ブラウザで「mail-form」フォルダ内の「error.html」にアクセス
    http://localhost/php-lessons/mail-form/error.html
ブラウザでの表示例

RERUN

入力チェック 必須項目などの入力チェック。

ユーザーから受け取ったデータをチェックし、セッションに格納する、
エラーがなければ入力確認画面にリダイレクトし、エラーがあれば入力フォームにリダイレクトする。

入力チェックを行って、
リダイレクトしてみよう。

  1. 「mail-form」フォルダ内の「set.php」をテキストエディタで開く
  2. エラーメッセージや、ユーザーから受け取ったデータをセッションに格納する為、
    セッションを開始しておく
mail-form/set.php
<?php
  // セッションの開始
  session_start();
  1. 入力フォームを経由して、このファイルにアクセスしているのかを確認する為、
    $_POSTが空じゃないかを確認する
    空の場合は、入力フォームにリダイレクトし処理を終了する。
mail-form/set.php
<?php
  // セッションの開始
  session_start();

  // ユーザーの送信内容が空だったらリダイレクト
  if ( empty($_POST) ) {
    header('Location: ./');
    exit();
  }
  1. $_SESSIONにエラーメッセージを格納するための配列を作成し、
    エラーがあれば、メッセージを追加する
mail-form/set.php
<?php
  // セッションの開始
  session_start();

  // ユーザーの送信内容が空だったらリダイレクト
  if ( empty($_POST) ) {
    header('Location: ./');
    exit();
  }

  // エラーメッセージ格納用の配列を初期化
  $_SESSION['error'] = array();

  // お名前の入力チェック
  if ( $_POST['name'] == '' ) {
    $_SESSION['error']['name'] = 'お名前を入力して下さい。';
  }

  // メールアドレスの入力チェック
  if ( !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
    $_SESSION['error']['email'] = 'メールアドレスの形式が正しくありません。';
  }

  if ( $_POST['email'] == '' ) {
    $_SESSION['error']['email'] = 'メールアドレスを入力して下さい。';
  }

  // お問い合わせ内容の入力チェック
  if ( $_POST['message'] == '' ) {
    $_SESSION['error']['message'] = 'お問い合わせ内容を入力して下さい。';
  }
  1. ユーザーの入力内容を$_SESSION['post']に格納
mail-form/set.php
<?php
  // セッションの開始
  session_start();

  // ユーザーの送信内容が空だったらリダイレクト
  if ( empty($_POST) ) {
    header('Location: ./');
    exit();
  }

  // エラーメッセージ格納用の配列を初期化
  $_SESSION['error'] = array();

  // お名前の入力チェック
  if ( $_POST['name'] == '' ) {
    $_SESSION['error']['name'] = 'お名前を入力して下さい。';
  }

  // メールアドレスの入力チェック
  if ( !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
    $_SESSION['error']['email'] = 'メールアドレスの形式が正しくありません。';
  }

  if ( $_POST['email'] == '' ) {
    $_SESSION['error']['email'] = 'メールアドレスを入力して下さい。';
  }

  // お問い合わせ内容の入力チェック
  if ( $_POST['message'] == '' ) {
    $_SESSION['error']['message'] = 'お問い合わせ内容を入力して下さい。';
  }

  // セッションにユーザーの送信内容を格納
  $_SESSION['post'] = $_POST;
  1. $_SESSION['error']にエラーメッセージがあるかを確認し、
    なければ入力確認画面へ、エラーメッセージがあれば入力フォームにリダイレクト
mail-form/set.php
<?php
  // セッションの開始
  session_start();

  // ユーザーの送信内容が空だったらリダイレクト
  if ( empty($_POST) ) {
    header('Location: ./');
    exit();
  }

  // エラーメッセージ格納用の配列を初期化
  $_SESSION['error'] = array();

  // お名前の入力チェック
  if ( $_POST['name'] == '' ) {
    $_SESSION['error']['name'] = 'お名前を入力して下さい。';
  }

  // メールアドレスの入力チェック
  if ( !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
    $_SESSION['error']['email'] = 'メールアドレスの形式が正しくありません。';
  }

  if ( $_POST['email'] == '' ) {
    $_SESSION['error']['email'] = 'メールアドレスを入力して下さい。';
  }

  // お問い合わせ内容の入力チェック
  if ( $_POST['message'] == '' ) {
    $_SESSION['error']['message'] = 'お問い合わせ内容を入力して下さい。';
  }

  // セッションにユーザーの送信内容を格納
  $_SESSION['post'] = $_POST;

  // エラーメッセージ格納用の配列が空かチェック
  if ( empty($_SESSION['error']) ) {
    // エラーなし
    header('Location: conf.php');

  } else {
    // エラーあり
    header('Location: ./');
  }
  exit();
  1. 上書き保存
  2. ブラウザで「mail-form」フォルダ内の「index.php」にアクセス
    http://localhost/php-lessons/mail-form/
  3. エラーの有無でリダイレクト先が変わることを確認
ブラウザでの表示例

RERUN

まとめ メールフォームには、
基本が詰まってる。

メールフォームにはサーバーサイドプログラミングの基本が詰まってる。

  • メール送信は文字化けとの戦い
  • 開発の規模が大きなる時は、表示部分のHTMLを先に作成しておく
  • 別途セキュリティへの配慮が必要