ユーザー情報をDBに登録する・その1  (PHP+PEARでウェブサービス勉強記録・3)

登録ユーザーのログイン・ログアウトの次は、実際にユーザーをユーザーDBに登録するためのロジックを開発してみます。

 

今回の流れ

今回の作業概要は以下のとおりです。

  • ユーザーがID・メールアドレス・パスワード・ユーザー名を入力。登録ボタンを押すと、ユーザーDBに登録される
  • 登録の際、ユーザーIDとメールアドレスの重複をチェックする。重複データがあった場合はエラーメッセージを表示して再入力を促す。
  • 登録の際に、データのエスケープ処理を行い、SQLインジェクションを回避する

実行結果

入力フォーム

registForm

入力データが無い状態で登録ボタンが押された場合

registForm_blank

入力データが重複していた場合

registForm_exist

入力が完了した場合

registForm_complete

 

データ登録ロジックと、ユーザー情報入力フォーム

ユーザーのデータ登録は、引き続き、PEAR::AUTHのメソッドを使います。

PEAR::AUTHには、ユーザー情報をデータベースに登録するためのメソッド「addUser()」が存在します。

このメソッドを利用して、DB登録を行います。

addUserの用法は、引数としてユーザーID、ユーザーパスワード、その他登録用のDBカラム名と、対応する登録データを引き渡す形になっています。ユーザー登録フォームを作ってデータを渡し、addUserでDBに引き渡せば良さそうです。

    require_once("Auth/Auth.php");

    $params = array(

        "dsn" => "mysqli://pear:peartest@localhost/pear",
        "table" => "auth",
        "usernamecol" => "username",
        "passwordcol" => "password",);

    $myAuth = new Auth("DB",$params,"");

    $myAuth -> addUser("$username", "$password", 
                        array("email" => "$email", "uname" => "$uname")
                       );

ただ、フォームから入力されたデータをそのままDB登録すると、既存のユーザーID、メールアドレスと重複することがありえます。

このため、入力データのチェック用ファイル「registChech.php」を作成、インクルードし、入力内容をチェック。DB内のユーザーデータと照合して、重複チェックを行います。

同時に、ユーザーID、メールアドレスが空ではないか、チェックを行います。

ユーザー情報の取得には、PEAR::DBを利用しました。

DBに登録されているユーザー情報をPEAR::DBで検索し、すでに登録済みかどうかをチェックする形にしてみました。

registCheck.php


<?php

/* 入力されたユーザーIDとパスワードを変数に取得 */

$username = $_POST["username"];
$email = $_POST["email"];

/* PEAR::DBを利用してユーザー名とメールアドレスの有無を取得 
すでに存在する場合、各変数にユーザーId、メールアドレスのみの配列が生成される
require_once("DB.php");

$dsn = "mysqli://pear:peartest@localhost/pear";

$myDB = DB::connect($dsn);
	
$user_exist = $myDB -> getRow("SELECT username FROM auth WHERE username='$username' ");
$email_exist = $myDB -> getRow("SELECT email FROM auth WHERE email='$email' ");


/* エラーメッセージ用変数 $regist_error 初期化 */

    unset($regist_error);

/* データ登録モードの場合、処理に入る */

if ($_POST["mode"] == check ) {

/* 入力されたIDが空か、もしくは登録済みでないかをチェック */
   

      if(empty($username)) {
    
      $regist_error = "IDは必須です。<br />";
    
    } elseif (!empty($user_exist)) {

    $regist_error .= "IDに入力した ".$username."はすでに使用されています。<br />";

    }

/* 入力されたメールアドレスが空か、もしくは登録済みでないかをチェック */


        if(empty($email)) {
    
        $regist_error .= "emailは必須です。<br />";

    }   elseif (!empty($email_exist)) {
    
    $regist_error .= "メールアドレスに入力した ".$email."はすでに使用されています。<br />";

    }
}

?>

PEAR::DBは、すでに古いライブラリで、一般的にはPEAR::MDB2の利用を推奨しているようですが、今回は勉強中であること、ベースとなるPEAR::DBを触っておいても損はないだろう、という理由から、PEAR::DBを利用しています。

データ登録時には、SQLインジェクションを避けるために、一度入力データをエスケープ処理します。

エスケープ処理には、mysql_real_escape_string関数を利用しました。

mysql_real_escape_string関数のマニュアルページを見ると、利用時にはMySQLに接続する必要があるようなので、エスケープ処理の前後に、接続=>切断の処理を行います。


/* データチェック後、エラーメッセージ変数
$regist_errorが空の場合=エラーがなかった場合
及び、フォーム入力後=hiddenで渡された値がcheckだった場合
データ登録を実行 */
    
if ($_POST['mode'] == check && empty($regist_error)) {

/* 登録情報のエスケープ処理を行ってデータベースに登録 */

    $conn = mysql_connect("localhost", "pear", "peartest");
    mysql_select_db(auth);
    
    if (get_magic_quotes_gpc()) {

        $username = stripslashes($_POST["username"]);
        $email = stripslashes($_POST["email"]);
        $password = stripslashes($_POST["password"]);
        $uname = stripslashes($_POST["uname"]);

    }

    $username = mysql_real_escape_string($username);
    $email = mysql_real_escape_string($email);
    $passsword = mysql_real_escape_string($password);
    $uname = mysql_real_escape_string($uname);

    mysql_close($conn);

    require_once("Auth/Auth.php");

    $params = array(

        "dsn" => "mysqli://pear:peartest@localhost/pear",
        "table" => "auth",
        "usernamecol" => "username",
        "passwordcol" => "password",);

    $myAuth = new Auth("DB",$params,"");

    $myAuth -> addUser("$username", "$password", 
                        array("email" => "$email", "uname" => "$uname")
                       );

 

流れをまとめると

  1. registForm.phpで、登録フォームを表示
  2. 入力データが存在した場合 (フォームがサブミットされた場合) 、registCheck.phpで入力データを検証。
  3. 入力データに不備があった場合、変数「$error_mesage」にエラーデータを登録。
  4. 変数$error_mesageが真だった場合=登録データにエラーがあった場合、エラー表示して、再入力を促す
  5. エラーがなかった場合、データ登録を実行し、登録完了メッセージを変数「$regist_complete」に登録して、表示を行う

というフローになります。

regist.Form.php

<?php

/* データチェックルーチンを読み込み */

include "registCheck.php";

/* データチェック後、エラーメッセージ変数
$regist_errorが空の場合=エラーがなかった場合
及び、フォーム入力後=hiddenで渡された値がcheckだった場合
データ登録を実行 */
    
if ($_POST['mode'] == check && empty($regist_error)) {

/* 登録情報のエスケープ処理を行ってデータベースに登録 */

    $conn = mysql_connect("localhost", "pear", "peartest");
    mysql_select_db(auth);
    
    if (get_magic_quotes_gpc()) {

        $username = stripslashes($_POST["username"]);
        $email = stripslashes($_POST["email"]);
        $password = stripslashes($_POST["password"]);
        $uname = stripslashes($_POST["uname"]);

    }

    $username = mysql_real_escape_string($username);
    $email = mysql_real_escape_string($email);
    $passsword = mysql_real_escape_string($password);
    $uname = mysql_real_escape_string($uname);

    mysql_close($conn);

    require_once("Auth/Auth.php");

    $params = array(

        "dsn" => "mysqli://pear:peartest@localhost/pear",
        "table" => "auth",
        "usernamecol" => "username",
        "passwordcol" => "password",);

    $myAuth = new Auth("DB",$params,"");

    $myAuth -> addUser("$username", "$password", 
                        array("email" => "$email", "uname" => "$uname")
                       );

    $regist_complete = "情報を登録しました。登録情報でログインできます。<br />";

}

?>

<!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" xml:lang="ja" lang="ja"> 

 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
	<title>情報登録ページ</title>
</head>


<body>

<h1>プロフィールの入力・更新</h1>

<?php

if (isset($regist_error)) {

    print ("<p><font color=\"red\">".$regist_error."</font></p>");

} elseif (isset($regist_complete) ){

    print ("<p><font color=\"red\">".$regist_complete."</font></p>");

}

?>

<form action="<? print($_SERVER['PHP_SELF']) ?>" method="post">

<input type="hidden" name="mode" value="check">

<table>
<tr>
<th>id:</th>
<td><input type="text" name="username" size="20"></td>
</tr>

<tr>
<th>Email:</th>
<td><input type="text" name="email" size="20"></td>
</tr>

<tr>
<th>パスワード:</th>
<td><input type="password" name="password" size="20"></td>
</tr>

<tr>
<th>表示名</th>
<td><input type="text" name="uname" size="20"></td>
</tr>

</table>

<input  type="submit" value="登録する">
</form>


</body>
</html>

 

フローチャート

今回の概要をフローチャートにすると、以下のようになるでしょうか。

registForm_flowchart

(フローチャート作成の練習で書いてみました。誤りを見つけた方は、ご指摘いただけると幸いです)

 

次回は入力データのベリファイを実装

今回のルーチンでは、重複チェックとブランクチェックのみを行っています。次回は、各項目の入力値をそれぞれ検証するためのルーチンを加えていきます。

 

今回の疑問

PEAR::AUTH、PEAR::DB、MySQL接続を、それぞればらばらに実行しているけど、もう少し良い方法ないだろうか。

今回はPEAR::DBを使っているが、PEAR::MDB2 に書き換える場合の修正点チェック

データ重複チェックの際に、わざわざPEAR::DBで配列を生成しているけど、これって問題ない?ユーザー情報のチェックは、素直にSQLでセレクト文を書いて、一致確認をしたほうが良いのかな?

ユーザーデータの重複チェックについては、他の方法がないか要検討。

phpのアプリは、初期のphp設定が、かなり重要な気がする。(magic_quote_gpcの設定など)