0

I'm working on a login system, however, I have encountered a problem. How come rowCount() always returns 0. I tried other ways but no luck. I did some research and found out that rowCount() only works with UPDATE, INSERT, AND DELETE, and not with SELECT.

Here's my original code:

       // Verify if password match 
        $hashedPwd = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $checkPwd = password_verify($pwd, $hashedPwd[0]["password"]);

        if($checkPwd === false){
            $stmt = null;
            header("Location: ../login.php?error=incorrect_password");
            exit();
        }
        else if($checkPwd === true){
            // Create prepared statement
            $stmt = $this->connect()->prepare('SELECT * FROM accounts WHERE username = ? AND password = ?;');

            // Execute prepared statement
            if(!$stmt->execute(array($uname, $pwd))){
                $stmt = null;
                header("Location: ../login.php?error=statement_failed");
                exit();
            }

            // Check if username and password exist in the database
            if($stmt->rowCount() === 0){
                $stmt = null;
                header("Location: ../login.php?error=user_not_found2");
                exit();
            }

            $user = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            // If everything is valid, grab data and assign it to a session and set cookie
            // Start session
            session_start();
            $_SESSION['id'] = $user[0]['id'];
            $_SESSION['username'] = $user[0]['username'];
            $_SESSION['user_type'] = $user[0]['user_type'];
            
            // Set cookie
            setcookie('uname', $uname, time()+60*60*24*30, "/");
        }

I tried using fetchColumn().

       if($checkPwd === false){
            $stmt = null;
            header("Location: ../login.php?error=incorrect_password");
            exit();
        }
        else if($checkPwd === true){
            // Create prepared statement
            $stmt = $this->connect()->prepare('SELECT count(*) FROM accounts WHERE username = ? AND password = ?;');

            // Execute prepared statement
            if(!$stmt->execute(array($uname, $pwd))){
                $stmt = null;
                header("Location: ../login.php?error=statement_failed");
                exit();
            }
             
            $row = $stmt->fetchColumn();

            // Check if username and password exist in the database
            if($row === 0){
                $stmt = null;
                header("Location: ../login.php?error=user_not_found");
                exit();
            }

I also made sure hashed password and user's password is matching and it is returning correct output

    $hashedPwd = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $checkPwd = password_verify($pwd, $hashedPwd[0]["password"]);

    if($checkPwd === false){
        $stmt = null;
        header("Location: ../login.php?error=incorrect_password");
        exit();
    }
    else if($checkPwd === true){
        // Returns true
    }
    else if($checkPwd === false){
      // Returns false
    }
    
    I tried logging in with correct and incorrect credentials and its completely fine.

What am I missing? Could someone please help.

  • 1
    When rowCount() returns 0, it means there is no data in the database to match the parameter in the query – Your Common Sense Oct 05 '22 at 10:39
  • Note that all those "header("Location: ../login.php?error" is a **very bad idea**. And only justified because neither of these conditions will actually work. So you can safely remove them – Your Common Sense Oct 05 '22 at 10:46
  • @YourCommonSense if that's the case, what's are the better ways to handle errors? – Programming is life Oct 05 '22 at 10:48
  • Basically, this entire code makes no sense, starting from that Verify if password match part. It should be replaces with [this](https://phpdelusions.net/pdo_examples/password_hash) – Your Common Sense Oct 05 '22 at 10:52
  • And error reporting is explained [here](https://phpdelusions.net/basic_principles_of_web_programming#error_reporting) – Your Common Sense Oct 05 '22 at 10:52
  • thank you so much for pointing out those mistakes! I learned a lot. – Programming is life Oct 05 '22 at 10:59
  • @YourCommonSense one more thing, how would I throw the error so the user could see it without using "header"? – Programming is life Oct 05 '22 at 11:05
  • Two options, if we exclude ajax: 1. write in the session, do a header redirect, read from the session, display to the user, delete from session. This is called Flash messages. 2. Have everything on the same page, the PHP code first and the HTML form below. Then just show the form back in case of error. On the same page, without redirects. – Your Common Sense Oct 05 '22 at 11:22

0 Answers0