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

Archives Details

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

PHP

2013.04.01

この記事は最終更新日から1年以上が経過しています。

前回の

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);

<pこちらはフォームのパスワードとデータベース内のパスワードが不一致は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

Comment

Related Article

php 7.4にアップデート

2023.12.24

Laravel 4 を PHP 7 環境へ移行したお話。

2018.06.10

PHP 簡易アクセスログ 出力

2016.04.29

Laravelを 別環境に移動したら画面が真っ白に。MacにComposer、php mcrypt 等をインストールしたお話。

2015.10.10

遅れましたが..あけましておめでとうございます!2015年は Laravelで画像処理。からということで。

2015.01.08

IDE phpstorm, IntelliJ IDEAの Database接続が便利すぎる件(Vagrant + IntelliJ IDEA でMySQL操作)

2014.11.29

Laravel4でもSmartyを使用したい!

2014.11.20

人気急上昇!PHPフレームワーク「Laravel」を使ってみました。簡易会員サイト作成編

2014.09.24

Laravel4 パーミッションエラー Vagrant パーミッションが変更しない件

2014.08.24

【CentOS6】 PHP5.3からPHP5.5にバージョンアップしました

2014.08.11

CATEGORY LIST

LATEST NEWS

Rust - Actix Web mongo ユーザー登録 JWT認証

Rust

2024.03.24

Rust - Actix Web JWT 認証認可 APIの作成

Rust

2024.02.25

Rust - Actix Web × JSON 静的ファイルをAPIで返却

Rust

2024.01.19

Rust - Actix Web × MongoDB環境をサクッと起動

Rust

2024.01.18

5分で学ぶ RustでWave Function Collapse (波動関数崩壊アルゴリズム)

Rust

2024.01.15

LLaMAモデル GGMLフォーマット(llama.cpp)をRustフレームワーク Leptosを用いて M1MacMiniでサクッと動かす。

Rust

2024.01.11

2024年 狙っているモバイルノートPC

tool

2024.01.07

MacOS XcodeにSDL2を追加

tool

2023.12.26

php 7.4にアップデート

PHP

2023.12.24

5分で覚える Flutter Flameで作る Wave Function Collapse - 波動関数崩壊アルゴリズム

AI・Bot・algorithm

2023.12.20

Flutter - Flameでゲーム作成 (キャラクターの移動)

Flutter

2023.07.23

Flutterで作る ChatGPT Prompt Manager

Flutter

2023.07.12

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

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

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

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

FOLLOW US