2013-03-05 110 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; 
    } 
}