このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

web帳

記事詳細

2013.04.01

PHP 会員制サイトの制作方法 その3

前回の

PHP 会員制サイトの制作方法 その2

の続きとなります。

今回は、

user_regist.php:会員登録と登録内容送信ファイル

index.php:ユーザー登録処理コントロールページ

の2ファイルを作成し、完成させましょう。

user_regist.php:会員登録と登録内容送信ファイル

前回作成したファイル regist_confirm.php:会員登録内容確認画面ファイルの後の処理のファイルとなります。

登録内容を確認したあと、データベースに各パラメーターを登録し、登録完了のメールを配信する流れとなります。

ソースはこちら。

<?php
/* 入力フォームからパラメータを取得 */
$formList = array('mode', 'input_userid', 'input_password', 'input_name', 'input_email');

/* ポストデータを取得しパラメータと同名の変数に格納 */
foreach($formList as $value) {
  $$value = $_POST[$value];
}

/* エラーメッセージの初期化 */
$error = array();

/* データベース接続設定 */
require_once('db.php');

/* ユーザーIDチェック */
$query = "select userid from members where userid = '$input_userid'"; 
$resultId = mysql_query($query);
	
if(mysql_num_rows($resultId) > 0 ) { //ユーザーIDが存在
  array_push($error,"このユーザーIDはすでに登録されています。");
}
	
if(count($error) == 0) {
  
  //登録するデーターにエラーがない場合、memberテーブルにデータを追加する。
  //トランザクション開始
  mysql_query("begin");
  
  $query = "insert into members(userid, password, name, email) values('$input_userid','$input_password','$input_name','$input_email')";
  $result = mysql_query($query);
  
  if($result){  //登録完了	
    //トランザクション終わり
    mysql_query("commit");
  
    /* 登録完了メールを送信 */
    mb_language("japanese");  //言語の設定
    mb_internal_encoding("utf-8");//内部エンコーディングの設定
  
    $to = $input_email;
    $subject = "会員登録URL送信メール";
    $message = "会員登録ありがとうございました。\n"."登録いただいたユーザーIDは[$input_userid]です。";
    $header = "From:test@test.com";
  
    if(!mb_send_mail($to, $subject, $message, $header)) {  //メール送信に失敗したら
      array_push($error,"メールが送信できませんでした。<br>ただしデータベースへの登録は完了しています。");
    }
  } else {	//データベースへの登録作業失敗
    //ロールバック
    mysql_query("rollback");	
    array_push($error, "データベースに登録できませんでした。");
  }
}
if(count($error) == 0) {	
?>
<table>
  <caption>データベース登録完了</caption>
  <tr>
    <td class="item">Thanks:</td>
    <td>登録ありがとうございます。<br>登録完了のお知らせをメールで送信しましたので、ご確認ください。</td>
  </tr>
</table>
<?php
/* エラー内容表示 */
} else {
?>
<table>
  <caption>データベース登録エラー</caption>
  <tr>
  <td class="item">Error:</td>
  <td>
  <?php
  foreach($error as $value) {
    print $value;
  ?>
  </td>
  </tr>
</table>
<?php
  }
}
?>

ではそれぞれ解説を行います。

regist_confirm.php からパラメータをポストで受け取る為に変数$formListに配列で格納していきます。

$formList = array('mode','pre_userid','input_userid','input_password','input_name','input_email');

regist_confirm.php 同様、変数$formListに格納した連想配列をそのまま$パラメータとし、変数と同名のパラメータをPOSTで受け取り、同名の変数に格納していきます。

foreach($formList as $value) {
  $$value = $_POST[$value];
}

regist_confirm.php 同様、エラーを初期化します。

$error = array();

データベースに接続します。

require_once('db.php');

ユーザーIDが重複していないか調べます。ユーザーIDがすでに存在する場合はエラー変数$errorにエラー文言を代入します。

$query = "select userid from members where userid = '$input_userid'"; 
$resultId = mysql_query($query);
if(mysql_num_rows($resultId) > 0 ) { 
  array_push($error,"このユーザーIDはすでに登録されています。");
}

エラーがない場合は次の処理へと移ります。

mysql_query("begin");

ここからトランザクションを開始していきます。

トランザクションとは、複数の処理がある場合、「すべての処理が成功したときにのみ成功」となり、一つでも失敗が発生すると「全て失敗」とすることを言います。

このような処理が必要な場面は銀行の振込みの処理などにも該当します。

AさんがBさんに10万振り込んだ際、Aさんの預金から10万の送金はされたが、Bさんの預金に不具合が生じ、振り込まれなかった。

この時、Aさんの処理を成功としてしまうと、不整合が発生してしまうため、Bさんの預金に入るまでの処理を成功とする必要があります。

今回の場合だと、複数カラムに代入する必要がありますので、全て格納されたときのみ成功としています。

$query = "insert into members(userid, password, name, email) values('$input_userid','$input_password','$input_name','$input_email')";
$result = mysql_query($query);

その後のメール配信の処理はPHP 会員制サイトの制作方法 1回目同様となります。(文言等は異なります。)

mysql_query("rollback");

データベースに登録失敗した際はロールバックの処理を行い、エラー変数 $errorにエラー文言を代入します。

if(count($error) == 0) { 

その後は、エラーをカウントし、エラーが存在しない場合は、データベース登録完了の文言を表示させます。

エラーが存在する場合は、

foreach($error as $value) {
  print $value;

foreachでエラーの数だけループし、表示させます。

index.php:ユーザー登録処理コントロールページ

と、一通りの処理は完成しましたので、それらをコントロールするページ index.phpを作成します。

<?php
/* 登録処理(終了を知らせる値)によって読み込むファイルを変える */
$mode = $_POST["mode"];

/* パラメーターに preuser_idがあれば登録フォームを表示 */
if($_GET['pre_userid'] !="") {
  $mode = "regist_form";
}

/* 振り分け処理 */
switch($mode) {
  // メールアドレスの登録と仮ID送信
  case"email_regist":
  $module = "email_regist.php";
  break;

  //会員登録フォーム
  case"regist_form":
  $module = "regist_form.php";
  break;

  //登録内容確認
  case"regist_confirm":
  $module = "regist_confirm.php";
  break;
	
  //会員登録
  case"user_regist":
  $module = "user_regist.php";
  break;
	
  //メールアドレス登録(初期画面)
  default:
  $module = "email_form.php";
  break;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="../css/style.css"/>
<title>会員登録フォーム</title>
</head>
<body>
<?php
  // コンテンツ(表示ページ)読み込み
  require_once($module);
?>
</body>
</html>

それでは解説を。

$mode = $_POST["mode"];

フォームを押した際にPOSTでパラメータmodeを渡しているので、受け取ったパラメータを$modeに代入します。

if($_GET['pre_userid'] !="") {
  $mode = "regist_form";
}

こちらはGETでpre_useridを受け取った際の処理となります。

つまり、

PHP 会員制サイトの制作方法 その2

の時の処理で、ユーザーがメールアドレスを登録し、仮IDを発行したメールのURLを開いたときの処理となります。

その時は、本登録の処理を行うので、modeはregist?formとなります。

$mode = "regist_form";

switch文を使い、modeによる切り替え処理を行います。

switch($mode) {
case"email_regist":
  $module = "email_regist.php";
  break;

modeがemail_registであれば、email_regist.phpと各modeに対してのファイルを変数$moduleに代入します。

require_once($module);

表示するのは、switch文を使い、各modeに対して代入した$moduleを表示させます。

これで会員の処理として一通り完了しました。

login.php:ログインページ

最後に、(ちょっと忘れておりました。)会員登録後、ユーザーがログインするページの作成を。ソースは以下のような感じで。

<?php
//セッション作成
session_start();

if(!isset($_POST['login'])) {
  //ログインフォームを表示
  inputForm();
} else {

  //フォームの値を取得
  $formUserId = $_POST['formUserid'];
  $formPassword = $_POST['formPassword'];
	
  //ID, PASWORDが未入力の場合
  if(($formUserId == "") || ($formPassword == "")) {
	
  //エラー関数の呼び出し
  error(1);
		
  } else { 
  //ID,PASSWORD 入力アリ	
  //データベースへ接続
  require_once('regist/db.php');
				
  //memberテーブルのデータを取得
  $query = "select * from members";
  $result = mysql_query($query);
		
  //フォームから取得したUSERIDとデータベース内のUSERIDが一致したらデータベースのPASSWORDを変数に格納		
  while($data = mysql_fetch_array($result)) {
    if($data['userid'] == $formUserId) {  //フォームから取得したUSERIDとデータベースのUSERIDが一致
      $dbPassword = $data['password'];
      break;
    }
  }
	
  //MySQLデータベースを閉じる
  mysql_close($conn);
  
  //$dbPasswordという変数に値が格納されていない場合→formUserIdとデータベースのIDが不一致
  if(!isset($dbPassword)) {
    error(2);
  } else {
  //formUserIdとデータベースのIDが一致
  //フォームのパスワードとデータベース内のパスワードが不一致
    if($dbPassword != $formPassword){
	  error(3);
	} else {
	  //ID,パスワードどちらも一致
	  //セッション変数を作成→セッション変数に $formUserID を登録
	  $_SESSION['loginUser'] = $formUserId;
	  header("Location:test.php");
	  }
	}
  }
}
?>
<?php
  //入力画面表示画面	
  function inputForm() {
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ログイン</title>
</head>
<body>
  <h1>ログインページ</h1>
  <form action="login.php" method="post">
  <label for="userid">ユーザーID</label>:
  <input type="text" name="formUserid" id="userid"/>
  <br />
  <label for="password">パスワード</label>:
  <input type="text" name="formPassword" id="password"/>
  <br />
  <input type="submit" name="login" value="ログイン" />
</form>
</body>
</html>
<?php
}

//エラー表示関数
function error($errorType) {
  
  switch($errorType) {
    case 1:
    $errorMsg = "IDとパスワードを入力してください。";
    break;
    
    case 2:
    $errorMsg = "IDが違います";
    break;
    
    case 3:
    $errorMsg = "パスワードが違います";
    break;
}
?>	
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ログイン</title>
</head>
<body>
<h1>エラーページ</h1>
<?php
  print $errorMsg;
?>
</body>
</html> 
<?php
}
?>

要点のみ、解説を。。

session_start();

今から、sessionを開始しますよーとのことで、

if(!isset($_POST['login'])) {

こちら、issetは変数がセットされており、それが NULLでないことを調べます。なので、されていない場合は、フォームを表示させる関数 inputForm(); を実行します。

$formUserId = $_POST['formUserid'];
$formPassword = $_POST['formPassword'];

フォームから受け取った値をそれぞれ、$formUserId、$formPasswordに代入します。

どちらも記入されていない場合は error(1);を実行。

$query = "select * from members";
$result = mysql_query($query);

データベース接続後のquery文となります。

while($data = mysql_fetch_array($result)) {
  if($data['userid'] == $formUserId) {
    $dbPassword = $data['password'];
    break;
  }
}

mysql_fetch_arrayは連想配列、添字配列、またはその両方として結果の行を取得します。それらを$dataに代入。

ここの処理として、フォームから取得したUSERIDとデータベース内のUSERIDが一致したらデータベースのPASSWORDを変数に格納しております。

mysql_close($conn);

しっかり閉じましょう。

if(!isset($dbPassword)) {
error(2);

 $dbPasswordという変数に値が格納されていない場合→つまり、formUserIdとデータベースのIDが不一致の場合はerror(2);を実行しております。

if($dbPassword != $formPassword){
  error(3);
$_SESSION['loginUser'] = $formUserId;
header("Location:test.php");

成功した際、セッション ‘loginUser’にユーザーidを代入して、test.phpにページ移動。

function error($errorType) {
  switch($errorType) {

エラーに関してはswitch文で振り分けそれぞれエラーメッセージを変えております。

style.css

最後、読み込むcssはこちらとなります。

@charset "UTF-8";
* {
  margin: 0px;
  padding: 0px;
}
a:link, a:visited {
  color: #C00;
  text-decoration: none;
}
a:hover {
  color: #F00;
}
body {
  background: #FFF;
  font-family: "ヒラギノ角ゴ Pro W3","MS Pゴシック",Osaka,sans-serif;
  font-size: 0.75em;
  color: #22304C;
}
table {
  width: 600px;
  margin: 20px auto;
  border: 1px solid #78849C;
}
caption {
  margin-bottom: 10px;
  text-align: left;
  font-size: 1.6em;
  color: #000;
}
td {
  padding: 8px 0px 8px 15px;
  border: 1px solid #B5BBC8;
}
td.item {
  background: #E7E9EF;
  color: #22304C;
}
div {
  width: 600px;
  margin: 0px auto;
  text-align: center;
}
div.error-msg {
  width: 600px;
  margin: 20px auto;
  text-align: left;
}

今回は基礎的なところなので、セキュリティが甘い部分だったり、遷移が無かったり、パスワードを入力時に表示されていたりと、多々足りない点がありますので任意で編集して頂ければと思います。

これらのソースはこちらにも公開しております。

Github

https://github.com/webcyou/sample/tree/master/php/members

  • RSSを登録する

  • follow us in feedly

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、港区六本木で活動中。

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。