2016-06-18 10 views
-1

最近、すべてのmySQLクエリでmySQLiからPDOを使用するように切り替えました。私は最近、Webアプリケーションを完成し、初めてPDOベースのサインアップ/サインインのワークフローを実装しています。PDOサインアップ機能が動作していないか、エラーがスローされています

大規模な調査の結果、私はPHPとPDOを登録してログインしました。申し込みの送信時に、ページがリフレッシュされ、DBに何も表示されず、ページがリダイレクトされません。

以下は、DBに接続し、ユーザーを登録し、プロファイルページにリダイレクトするためのコードです。

registerUser.php

<?php 
error_reporting(E_ALL); 
ini_set('display_errors', 1); 

require 'dbconfig.php'; 

$url = "http://mattmcclintock.com"; 

$uname = null; 
$umail = null; 
$upass = null; 
$unem = array($uname, $umail); 
$umore = array($uname, $umail, $upass); 
$errors = array(); 

$message = null; 

if (isset($_POST['btn-signup'])) { 
// good idea to trim non-password fields 
$uname = trim($_POST['txt_uname']); 
$umail = trim($_POST['txt_umail']); 
$upass = $_POST['txt_upass']; 

// I am assuming you want to check every field independently, so you need to 
// group your IF conditions for each field 

// empty string is a falsey (i.e. '' == false => true; though '' === false => false), 
// so we'll shorten your IF conditions from $var == '' to !$var 
    if (!$uname) { 
    $errors['txt_uname'] = "provide username !"; 
    } 

    if (!$umail) { 
    $errors['txt_umail'] = "provide email id !"; 
    } elseif (!filter_var($umail, FILTER_VALIDATE_EMAIL)) { 
    $errors['txt_umail'] = 'Please enter a valid email address !'; 
    } 

    if (!$upass) { 
    $errors['txt_upass'] = "provide password !"; 
    } elseif (strlen($upass) < 6) { 
    $errors['txt_upass'] = "Password must be atleast 6 characters"; 
    } 


    // Assuming you only want to check for duplications when there are no errors with the username or email 

    if (empty($errors['txt_umail']) && empty($errors['txt_umail'])) { 
     if ($row = $user->getUserByUsernameOrEmail($uname, $umail)) { 
     if ($row['user_name'] == $uname) { 
      $errors['txt_uname'] = "sorry username already taken !"; 
     } else { 
      $errors['txt_umail'] = "sorry email id already taken !"; 
     } 
    } 
} 

// empty array is also a falsey 
if ($errors) { 
    $message = "There are errors"; 

// WHOA! where did $fname and $lname come from?! 
// original: if($user->register($fname,$lname,$uname,$umail,$upass)) { 

} elseif ($user->register($uname, $umail, $upass)) { 
    $user->redirect($url); 
} else { 
    $message = "An unexpected error has occurred"; 
} 
} 
?> 

としてサインアップするための対応するHTML。

<form id="signupform" method="POST" action="registerUser.php" class="form-horizontal" role="form"> 
        <div id="signupalert" style="display:none" class="alert alert-danger"> 
         <p>Error:</p> 
         <span></span> 
        </div> 
        <div class="form-group"> 
         <label for="email" class="col-md-3 control-label">Username</label> 
         <div class="col-md-9"> 
          <input type="text" class="form-control" name="txt_uname" placeholder="Enter Username" value="<?php if(isset($error)){echo $uname;}?>" /> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label for="firstname" class="col-md-3 control-label">Email</label> 
         <div class="col-md-9"> 
          <input type="text" class="form-control" name="txt_umail" placeholder="Enter E-Mail ID" value="<?php if(isset($error)){echo $umail;}?>" /> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label for="password" class="col-md-3 control-label">Password</label> 
         <div class="col-md-9"> 
          <input type="password" class="form-control" name="txt_upass" placeholder="Enter Password" /> 
         </div> 
        </div> 
        <div class="form-group"> 
         <!-- Button -->           
         <div class="col-md-offset-3 col-md-9"> 
          <button type="submit" class="btn btn-block btn-primary" name="btn-signup"> 
          <i class="glyphicon glyphicon-open-file"></i>&nbsp;SIGN UP 
          </button>   
         </div> 
       </form> 

ご協力いただければ幸いです。 PDOへのSQLの切り替えだけで書かれていることは比較的困難であり、私はすべての一般的なDBのやりとりやPDOを使ってそれらを処理する方法を感じています。

Iはclass.user.php

class.User.php

​​

dbconfig.php

<?php 

session_start(); 

$DB_host = "bbb"; 
$DB_user = "bbb"; 
$DB_pass = "bbb"; 
$DB_name = "bbb"; 

try 
{ 
$DB_con = new PDO("mysql:host={$DB_host};dbname= {$DB_name}",$DB_user,$DB_pass); 
$DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
} 
catch(PDOException $e) 
{ 
echo $e->getMessage(); 
} 


include_once 'class.User.php'; 
$user = new USER($DB_con); 
+0

Userクラスを提供できますか? –

+0

ユーザークラスを含む投稿を編集しています。ありがとうございました。 – Emily

+1

エラーをオンにします。$ DB_con-> setAttribute(PDO :: ATTR_ERRMODE、PDO :: ERRMODE_EXCEPTION); – WhoIsRich

答えて

1

さて、そうであっても、この場合のコードを追加下記あなたが書いたように働いていましたが、まだ警告/エラーが表示されているはずですので、最初にやることをお勧めしますエラーログを見つけるか、エラー報告を有効にします。

エラーのほとんどは、基本的なエラー処理によって取得されるため、いくつかの点を説明します。これは厳密には「答え」ではない(私はいくつかの下降音が期待されるはずだが)。

だから、始めましょう。

まず:

$stmt = $DB_con->prepare("SELECT user_name,user_email FROM users WHERE user_name=:uname OR user_email=:umail"); 
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail)); 
$row=$stmt->fetch(PDO::FETCH_ASSOC); 

if($row['user_name']==$uname) { 
    $error[] = "sorry username already taken !"; 
} 
else if($row['user_email']==$umail) { 
    $error[] = "sorry email id already taken !"; 
} 
else 
{ 
    if($user->register($fname,$lname,$uname,$umail,$upass)) 
    { 
     $user->redirect('me.php'); 
    } 
} 

はのは、電子メールアドレス/ユーザー名コンボがとられていなかったと仮定しよう。この場合、$rowはnullなので、$rowは配列ではないため、$row[whatever]は警告をスローします。したがって、ifブロックのソートを開始します。

$stmt = $DB_con->prepare("SELECT user_name,user_email FROM users WHERE user_name=:uname OR user_email=:umail"); 
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail)); 
$row=$stmt->fetch(PDO::FETCH_ASSOC); 

if($row) { 
    if($row['user_name']==$uname) { 
     $error[] = "sorry username already taken !"; 
    } 
    else 
    { 
     $error[] = "sorry email id already taken !"; 
    } 
} 
else 
{ 
    if($user->register($fname,$lname,$uname,$umail,$upass)) 
    { 
     $user->redirect('me.php'); 
    } 
} 

次に、あなたのregisterメソッド内では、再度、実際に何が起こっているか、実際に働いていたかどうかをチェックしません。エラー報告が無効になっているように見える場合は、の値がprepareの後にあるかどうかテストし、falseを返す可能性があるexecuteの結果をテストする必要があります。値を見つけたら、何が起きているのかを調べることができます。

最後に、ちょっとしたメモです。 trim($_POST['txt_upass'])と同じように、ユーザーが入力としてパスワードを変更するべきではありません。なぜなら、検証時に同じではないので、別の値にハッシュするからです。

ほんの少し役に立ちます。

+0

トリムを取り除き、コードをアクション時に呼び出された独自のファイルに分割し、1人のユーザーを作成しましたが、ある時点でコードを破棄するために変更を加えました。また、登録後の私のリダイレクトは機能していません。上記のコードを更新しました。 – Emily

+0

コードを上記の提案で更新しました。私のフォームバリューの提出が私のデータベースにない理由を教えても、PDOエラー報告を受け取ることができません。 – Emily

0

あなたの問題は多くのことになる可能性があるので、私はあなたのコードをいくつかのコメントとともに行ごとに見直します。

class.user.php

<?php 
class USER 
{ 
    private $db; 

    public function __construct($DB_con) 
    { 
     $this->db = $DB_con; 
    } 

    public function getUserByUsernameOrEmail($uname, $umail) 
    { 
     try { 
      $stmt = $this->db->prepare(" 
       SELECT user_name, user_email FROM users WHERE user_name= ? OR user_email = ? 
      "); 
      $stmt->execute(array($uname, $umail)); 
      return $stmt->fetch(); 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
     return null; 
    } 

    public function register($uname, $umail, $upass) 
    { 
     try { 
      $stmt = $this->db->prepare(" 
       INSERT INTO users (user_name, user_email, user_pass) VALUES(?, ?, ?) 
      "); 
      $stmt->execute(array($uname, $umail, $upass)); 
      return $stmt->rowCount(); 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
     return false; 
    } 

    public function login($uname, $umail, $upass) 
    { 
     try { 
      $stmt = $this->db->prepare("SELECT * FROM users WHERE user_name = ? OR user_email= ?"); 
      $stmt->execute(array($uname, $umail)); 
      $row = $stmt->fetch(); 
      // this will only work PHP >= 5.5.0 
      //if (password_verify($upass, $row['user_pass'])) { 
      if ($row && $row['upass'] === $upass) { 
       $_SESSION['user_session'] = $row['user_id']; 
       return true; 
      } 
     } catch (PDOException $e) { 
      echo $e->getMessage(); 
     } 
     return false; 
    } 

    public function is_loggedin() 
    { 
     return isset($_SESSION['user_session']); // shortened 
    } 

    public function redirect($url) 
    { 
     header("Location: $url"); 
     exit; 
    } 

    public function logout() 
    { 
     session_destroy(); 
     unset($_SESSION['user_session']); 
     return true; 
    } 
} 
?> 

dbconfig.php

<?php 
session_start(); 

$DB_host = "bbb"; 
$DB_user = "bbb"; 
$DB_pass = "bbb"; 
$DB_name = "bbb"; 

try { 
    $DB_con = new PDO("mysql:host={$DB_host};dbname={$DB_name}",$DB_user,$DB_pass); 
    $DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $DB_con->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
} catch (PDOException $e) { 
    echo $e->getMessage(); 
} 

include_once 'class.User.php'; 

$user = new USER($DB_con); 
?> 

registerUser.php

<?php 
// good idea to turn on the errors during development 
error_reporting(E_ALL); 
ini_set('display_errors', 1); 

require_once 'dbconfig.php'; 

$url = "http://mattmcclintock.com"; 

$uname = null; 
$umail = null; 
$upass = null; 

// always declare the variables that you will be using 

// this will be an associative array where the keys will be the name of the fields and the values will be their associated error message 
$errors = array(); 

// new: this will hold the main error message 
$message = null; 

if (isset($_POST['btn-signup'])) { 
    // good idea to trim non-password fields 
    $uname = trim($_POST['txt_uname']); 
    $umail = trim($_POST['txt_umail']); 
    $upass = $_POST['txt_upass']; 

    // validate fields 

    if (!$uname) { 
     $errors['txt_uname'] = "provide username !"; 
    } 

    if (!$umail) { 
     $errors['txt_umail'] = "provide email id !"; 
    } elseif (!filter_var($umail, FILTER_VALIDATE_EMAIL)) { 
     $errors['txt_umail'] = 'Please enter a valid email address !'; 
    } 

    if (!$upass) { 
     $errors['txt_upass'] = "provide password !"; 
    } elseif (strlen($upass) < 6) { 
     $errors['txt_upass'] = "Password must be atleast 6 characters"; 
    } 

    if (empty($errors['txt_uname']) && empty($errors['txt_umail'])) { 
     if ($row = $user->getUserByUsernameOrEmail($uname, $umail)) { 
      if ($row['user_name'] == $uname) { 
       $errors['txt_uname'] = "sorry username already taken !"; 
      } else { 
       $errors['txt_umail'] = "sorry email id already taken !"; 
      } 
     } 
    } 

    if ($errors) { 
     $message = "There are errors"; 
    } elseif ($user->register($uname, $umail, $upass)) { 
     $user->redirect($url); 
    } else { 
     $message = "An unexpected error has occurred"; 
    } 
} 
?> 

<form id="signupform" method="POST" action="registerUser.php" class="form-horizontal" role="form"> 
    <div id="signupalert" style="display:none" class="alert alert-danger"> 
     <p>Error: <?= $message ?></p> 
     <?php foreach ($errors as $name => $message) : ?> 
      <span><?= $message ?></span><br> 
     <?php endforeach ?> 
    </div> 
    <div class="form-group"> 
     <label for="email" class="col-md-3 control-label">Username</label> 
     <div class="col-md-9"> 
      <input type="text" class="form-control" name="txt_uname" placeholder="Enter Username" value="<?= $uname ?>"> 
     </div> 
    </div> 
    <div class="form-group"> 
     <label for="firstname" class="col-md-3 control-label">Email</label> 
     <div class="col-md-9"> 
      <input type="text" class="form-control" name="txt_umail" placeholder="Enter E-Mail ID" value="<?= $umail ?>"> 
     </div> 
    </div> 
    <div class="form-group"> 
     <label for="password" class="col-md-3 control-label">Password</label> 
     <div class="col-md-9"> 
      <input type="password" class="form-control" name="txt_upass" placeholder="Enter Password"> 
     </div> 
    </div> 
    <div class="form-group"> 
     <!-- Button -->           
     <div class="col-md-offset-3 col-md-9"> 
      <button type="submit" class="btn btn-block btn-primary" name="btn-signup"> 
      <i class="glyphicon glyphicon-open-file"></i>&nbsp;SIGN UP 
      </button>   
     </div> 
    </div> 
</form> 

IMO IあなたのUSERクラスはあまりにも多くのことをしており、Single Responsibility Principleに違反していると思います。

ブール値の詳細については、linkをお読みください。

リダイレクトの詳細については、postの回答をご覧ください。

+0

ありがとうございました。これまでのところ、誰かが新しいメソッド、この場合はPDO Register/Sign Inのフローをstackoverflowで学ぶのを助けてくれた最も有用で効率的な方法です。大変感謝しています。 – Emily

+0

私はPDOエラーメッセージにいくつか問題があります。上記の2つのスクリプトを更新します。 – Emily

+0

コードを更新しました。ユーザーは作成されておらず、リダイレクトが多すぎるページにはアクセスできません。 – Emily

関連する問題