【コピペで使える】PHP空メール登録機能実装サンプル

はじめに

ウェブサービスでの会員登録において、空メールは非常に利便性の高いしくみです。

一般的には会員登録はウェブページ上の登録フォームで行いますが、フォームに自身のメールアドレスを入力する作業というのは思いのほか大変です。

自分のメールアドレスを正確に覚えてないような場合は、まず自分のメールアドレスを確認する作業をしなければなりませんし、もし自分のメールアドレスを間違って入力してしまった場合には、ログインができなくなるケースが考えられます。

空メールは、実際に送信されたメールの情報からメールアドレスを取得するため、こういった問題をすべてクリアすることができます。

特に出先での会員登録が想定されるようなサービスでは、必須の機能ということができます。

今回は、そんな空メール機能をPHPとMySQLで実現する実装サンプルを紹介したいと思います。
 

処理の概要

今回のプログラムでは、ウェブページ上のリンクから空メールを送信し、送信されたメールアドレスをデータベース内の会員情報テーブルに登録するまで一連の処理を実現したいと思います。

実際のサービスへの実装では、メールアドレス登録後にパスワードや詳しい会員情報を設定してもらうようなフォームを案内する必要が出てくるかと思いますが、ここまでを対象にするとシンプルさを欠きますので、そういった部分は各実装者で工夫をして頂きたいと思います。
 

実装環境

今回この処理を実装する環境としては、ロリポップレンタルサーバーのLAMP環境を使用します。

PHPのライブラリや、SSHを使用した処理などが必要ない方法で実装を目指します。
 

処理のフロー

以下、今回の処理のフローです。

空メール送信(HTML)

受信メールのメールアドレス抽出とDB登録(CRON/PHP/MySQL)

非常にシンプルですね。
 

実装(コーディング)サンプル

DB

membersテーブル

id
email(text)

上記が今回のサンプルプログラムで使用する会員情報テーブルの構成となります。
※今回はパスワード等会員情報は省きます。

HTML

send.html


<a href="mailto:karamail@tadworks.jp?subject=空メール送信&body=このままメールを送信してください。">空メールを送信する</a>

※受信用メールアドレスは各自準備をお願いします。

PHP

recieve.php


// メールサーバー情報
define("MAIL_HOST", "【メールサーバー名】");
define("MAIL_USER", "【ユーザー名】);
define("MAIL_PASS", "【パスワード】");

// メールサーバーに接続
$filePointer = fsockopen(MAIL_HOST, 110, $errNo, $errStr, 10);
$memo = fgets($filePointer, 512);
fputs($filePointer, "USER ".MAIL_USER."\r\n");
$memo = fgets($filePointer, 512);
fputs($filePointer, "PASS ".MAIL_PASS."\r\n");
$memo = fgets($filePointer, 512);
fputs($filePointer, "STAT\r\n");
$memo = fgets($filePointer, 512);
list($strings, $cnt, $size) = explode(' ', $memo);
if (intVal($cnt) == 0) {
  $announcement = '新着メールはありません。';
} else {
  $announcement = '新着メールがあります。';
}
for ($i = 1; $i <= $cnt; $i++) {
  fputs($filePointer, "RETR $i\r\n");
  $gyo = fgets($filePointer, 512);
  while (!preg_match("/^\.\r\n/", $gyo)) {
    $gyo = fgets($filePointer, 512);
    $allGyo[$i] .= $gyo;
  }
  if (intVal($cnt) !== 0) {
    fputs($filePointer, "DELE $i\r\n");
    $gyo = fgets($filePointer, 512);
  }
}
fputs($filePointer, "QUIT\r\n");
fclose($filePointer);

// 処理
$data = array();
if(!empty($allGyo)){
  foreach($allGyo as $val){
    $i++;
    // メールアドレスの抽出
    $data[$i] = mb_convert_encoding($val, "UTF-8", "auto");
    $email = substr($data[$i], $of=strpos($data[$i],'Return-Path: <')+14,strpos($data[$i],'>')-$of);
    if(insertEmail($email)){
      // 登録完了後の処理
    }
  }
}
exit;

サーバーの負荷は少々高くなることが想定されますが、このPHPファイルをcronで定期的(5分毎など)に実行することで、新規の空メールの受信を検知して登録処理を実現することができるでしょう。

※本来であればメール受信をトリガーにこのファイルを実行するのが無駄はないと思います。

実際に使う際には、発行した登録フォームのURLなどを記載した自動返信メールの送信処理なども追加する必要があるものと思いますが、その辺は個別にカスタマイズをお願いします。

db.php


define("DB_HOST", "【データベースサーバー名】");
define("DB_USER", "【ユーザー名】");
define("DB_PASS", "【パスワード】");
define("DB_NAME", "【データベース名】");

function insertEmail($email){
  // データベースからリスト取得
  $db = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASS);
  // 文字コードセット
  $db->query('SET NAMES utf8');
  // SQL文作成
  $sql = "INSERT INTO members (email) VALUES (:email);";
  // クエリ
  $stt = $db->prepare($sql);
  // 変数設定
  $stt->bindParam(':email', $email);
  // クエリ実行
  $ret = $stt->execute();
  return $ret;
}

 

まとめ

いかがでしたでしょうか?

空メールの実装というととても難しそうに感じますが、レンタルサーバーでも意外と簡単に実現できることがわかるかと思います。

実際のサービスへの実装では、もう少し複雑になってくると思いますが、基本的な処理の流れは変わらないのではないかと思います。

是非参考にして頂ければと思います。

※もし内容に不備などございましたらご連絡頂けると幸いです。