2013-03-05 184 views
0

我想創建一個簡單的登錄系統,我查詢用戶提供的用戶名是否存在於數據庫中。但是我在取回rowcount時遇到了問題。我一直在獲取不確定的變量num: error.I也嘗試過使用,未定義的變量:num

$num = $stmt->rowCount(); 

但然後我得到了調用一個成員函數rowCount時()一個非對象error.I很新的PHP和web開發,這讓我感到困惑,我不要不知道如何讓它工作,有人可以幫我嗎?這裏是db.php文件的代碼

<?php 
require "config.php"; 


function DBconnect($config) { 
    try { 
     $conn = new PDO('mysql:host=localhost;dbname=' . $config['database'], 
         $config['username'], 
         $config['password']); 

     $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

     return $conn; 
    } catch(Exception $e) { 
     return false; 
    } 
} 

function query($query, $bindings, $conn) { 
    $stmt = $conn->prepare($query); 
    $stmt->execute($bindings); 

    return $stmt; 
} 

這裏是index.php文件的代碼,它是登錄頁面。

<?php 

// Allow sessions to be passed so we can see if the user is logged in 
session_start(); 

// include the necessary files 
require "db.php"; 
require "functions.php"; 
include "index.view.php"; 


//conect to the database so we can check, edit or ,data to our users table 
$conn = DBconnect($config); 

// if the user has submitted the form 
if($_SERVER["REQUEST_METHOD"] === "POST") { 

    //protect the posted value then store them to variables 
    $username = protect($_POST["username"]); 
    $password = protect($_POST["password"]); 

    //Check if the username or password boxes were not filled in 
    if (!$username || !$password){ 
     // if not display an error message. 
     echo "You need to fill in a username and password!"; 
    }else 
     // if correct continue cheking 

     //select all the rows where the username and password match the ones submitted by the user 
     query( "SELECT * FROM users WHERE username = :username", 
       array("username" => $username), 
       $conn); 
     $num = $stmt->fetchColumn(); 


     //check if there was not a match 
     if($num == 0) { 
      //if not display an error message 
      echo "The username you entered does not exist!"; 
     }else{ 
      //if there was a mactch continue chekcing 

      //select all rows where the username and password match the ones submitted by the user 
      query("SELECT * FROM users WHERE username =:username && password = :pasword", 
        array("username" => $username, "password" => $password), 
        $conn); 
      $num = $stmt->fetchColumn();  

      //check if there was not a match 
      if($num == 0) { 
       //if not display error message 
       echo "Username and password do not mactch"; 
      }else { 
       //if there was continue checking 

       //split all the fields from the correct row into an associative array 
       $row = $user->fetch(PDO::FETCH_ASSOC); 
       //check to see if the user has not activated their account 
       if($row["active"] != 1) { 
        //if not display an error message 
        echo "You have not yet activated your account!"; 
       }else { 
        //if so then log them in 

        // set the login session storing their id. We use this to 
        // see if they are logged in or not. 
        $_SESSION["uid"] = $row["id"]; 
        //show message confirming that they are loggd in 
        echo "You have succesfully logged in!"; 
        //update the online field to 50 seconds in the future 
        $time = date("u")+50; 
        query("UPDATE users SET online = :time WHERE id = :id", 
          array("time" => $time, "id" => $_SESSION["uid"]), 
          $conn); 
        //redirect them to the usersonline page 
        header("Location: usersOnline.php"); 
       } 
      } 


    } 
}   

回答

2

你錯過了搶$stmtquery()返回值。切換到來電:

$stmt = query(....); 
$num = $stmt->rowCount(); 

請注意,它被認爲是不安全作出詳細通知有關

  • 的用戶名是錯誤的
  • 的密碼是錯誤的
  • 兩者是錯誤。

如果這樣做,攻擊者很容易獲得有效的用戶名。擁有用戶名的Onece需要更少的努力才能獲得有效帳戶的密碼。

另外,我不會使用rowCount(),因爲行數不會被每個數據庫驅動程序返回。因此,如果您曾經使用過不同的數據庫,代碼可能會失敗。

變化THG查詢:

SELECT count(*) AS number_of_rows, * FROM users WHERE username =:username && password = :pasword" 

...然後取出從結果集 'NUMBER_OF_ROWS':

if (!$username || !$password){ 
    // if not display an error message. 
    echo "You need to fill in a username and password!"; 
}else 

    //select the number of rows where the username and password match the ones submitted by the user 
    query( "SELECT count(*) as number_of_records, * FROM users WHERE username = :username AND password = :password", 
      array("username" => $username, "password" => "$password"), 
      $conn); 
    $record = $stmt->fetch(); 
    if($record['number_of_records'] !== '1') { 
     echo 'wrong username and/or password'; 
    } 
} 

此外應注意:DO絕不會存儲未加密的密碼數據庫中的

取而代之,你應該存儲密碼散列鹽漬單向散列函數如sha1或md5。爲了簡潔起見,我不會在這裏舉一個例子。我會谷歌這個或要求提出另一個問題。

+0

感謝我試過,但後來我得到的[致命錯誤:未捕獲的異常「PDOException」有消息「SQLSTATE [HY093]:無效的參數號:參數未定義'在第21行的C:\ wamp \ www \ sideProjects \ loginTut \ db.php中]錯誤:S我也得到PDOException:SQLSTATE [HY093]:參數號無效:參數未定義在第21行錯誤的C:\ wamp \ www \ sideProjects \ loginTut \ db.php中,我找不出它們的含義:S – Brock90 2013-03-05 11:58:01

+0

@ Brock90嘿,現在不得不離開電腦。如果您願意,可以稍後幫助您解決語法錯誤。在這期間,你應該嘗試自己;)。如果你有進一步的問題,請在這裏留下評論..看到你 – hek2mgl 2013-03-05 12:17:00

+0

謝謝你的幫助我得到了網頁的工作,但我想問你知道更好的方式來顯示錯誤,而不是echo.i試着把一個空的數組在頁面頂部$ data = array();然後將所有回聲「.....」更改爲$ data [「status」] =「......」,在我的視圖頁上,我做了<?如果isset($ stsus):?>

<?= $ status; ?>

<?php endif; ?>但由於某種原因,它不起作用。並感謝您的幫助。 – Brock90 2013-03-05 13:51:29

1

您的query()函數返回一個語句,但您不保存您調用它的返回值。

變化

query(.....); 

$stmt = query(.....); 
0

我無法忍受這樣臃腫的代碼。 所以,這裏是一個正確的版本,沒有所有無用的和不必要的錯誤代碼:

if($_SERVER["REQUEST_METHOD"] == "POST") { 
    $sql = "SELECT id,active FROM users WHERE username=? && password=?"; 
    $stm = query($sql, array($_POST["username"], $_POST["password"]), $conn); 
    $row = $stm->fetch(PDO::FETCH_ASSOC); 
    if(!$row) { 
     echo "Username and password do not mactch"; 
    } elseif($row["active"] != 1) { 
     echo "You have not yet activated your account!"; 
    } else { 
     $_SESSION["uid"] = $row["id"]; 
     $time = date("u")+50; 
     $sql = "UPDATE users SET online=? WHERE id=?"; 
     query($sql, array($time, $row["id"]), $conn); 
     header("Location: usersOnline.php"); 
     exit; 
    } 
}