mysqli num_rows从mysqli OOP样式返回0

时间:2017-10-08 02:04:37

标签: php oop mysqli

我正在使用mysqli OOP样式登录脚本。我编写echo脚本来检查它是否获取了数据。结果是登录数据。但是,当我想查看num_rows时,即使我使用$stmt->store_result,它也会返回零。我在这个网站上搜索了许多主题并且它不起作用。 mysqli_num_rows也不起作用。或者我只是错过了一些数据存储顺序?

这是我的代码。

<?php
require_once "condb.php";

if (!isset($_POST['LOGIN']))
  {header("Location:index.php");}

else
{

  $username=mysqli_real_escape_string($cn,$_POST['username']);
  $password=mysqli_real_escape_string($cn,$_POST['password']);
  $hashed_password=password_hash($password,PASSWORD_DEFAULT);

  $login = $cn->prepare("SELECT name,username,password,status
                       FROM login WHERE username=?");

  $login->bind_param("s", $username);
  $login->execute();
  $login->bind_result($name,$username,$password,$status);
  $login->store_result();
  $login->fetch();
  $count=$login->num_rows();

  echo $name."<br />".
  $username."<br />".
  $password."<br />".
  $status."<br />".$count;

/*Below here is if condition that I'll used when I finished solving this 
problem.*/

/*
if ($count > 0 )
{
   if(password_verify($password, $row['password']) && 
   $row['status']=="Admin")
   {
   echo "ok<br>You are Admin!";
   header("Location:admin/admin.php");
   $login->close();
   }elseif(password_verify($password, $row['password']) && 
    $row['status']=="Editor")
    {
      echo "ok<br>You are Editor!";
      $login->close();
    }elseif(password_verify($password, $row['password']) && 
    $row['status']=="Author")
    {
      echo "ok<br>You are Author!";
      $login->close();
     }
 else
 {
   echo "Username or password incorrect";
   $login->close();
   }
}
*/
}
?>

3 个答案:

答案 0 :(得分:0)

  • 如果您正在准备sql语句,请不要再使用mysqli_real_escape_string(),因为准备过程已经意味着转义。因此,通过使用预处理语句,您可以安全地了解MySQL注入。
  • num_rows不是方法,而是属性:$count = $login->num_rows;
  • 您应该使用异常处理以便能够捕获最终错误。
  • 对变量,属性和方法使用意图揭示,可发音的名称。并且不要害怕提供长的。见Clean, high quality code guide。示例:dbconnection.php代替condb.php$connection代替$cn$statement代替$login

也许这些答案对你也有帮助。

祝你好运!

<?php

require_once 'condb.php';

/*
 * Enable internal report functions. This enables the exception handling, 
 * e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions 
 * (mysqli_sql_exception). They are catched in the try-catch block.
 * 
 * MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
 * MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings. 
 * 
 * See:
 *      http://php.net/manual/en/class.mysqli-driver.php
 *      http://php.net/manual/en/mysqli-driver.report-mode.php
 *      http://php.net/manual/en/mysqli.constants.php
 */
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

if (!isset($_POST['LOGIN'])) {
    header('Location: index.php');
    exit();
} else {
    try {
        $username = $_POST['username'];
        $password = $_POST['password'];

        $sql = 'SELECT 
                name,
                username,
                password,
                status 
            FROM login 
            WHERE username = ?';

        $statement = $connection->prepare($sql);
        $statement->bind_param('s', $username);
        $statement->execute();
        $statement->store_result();

        $count = $statement->num_rows;

        if ($count > 0) {
            $varsBound = $statement->bind_result($resultName, $resultUsername, $resultPassword, $resultStatus);

            $fetched = $statement->fetch();

            // For testing.
            var_dump($resultName);
            var_dump($resultUsername);
            var_dump($resultPassword);
            var_dump($resultStatus);

            if (password_verify($resultPassword, password_hash($password, PASSWORD_DEFAULT))) {
                switch ($resultStatus) {
                    case 'Admin':
                        echo 'You are an Admin!';
                        // header("Location: admin/admin.php");
                        // exit();
                        break;

                    case 'Editor':
                        echo 'You are an Editor!';
                        //...
                        break;

                    case 'Author':
                        echo 'You are an Author!';
                        //...
                        break;

                    default:
                        //...
                        break;
                }
            } else {
                echo 'Invalid password!';
            }
        } else {
            echo 'Invalid user name or no record found for the given user name!';
        }

        $statement->free_result();
        $statement->close();
        $connection->close();
    } catch (mysqli_sql_exception $e) {
        echo 'Error: ' . $e->getCode() . ' - ' . $e->getMessage();
        exit();
    } catch (Exception $e) {
        echo $e->getMessage();
        exit();
    }
}

/*
 * Disable internal report functions.
 * 
 * MYSQLI_REPORT_OFF: Turns reporting off.
 * 
 * See:
 *      http://php.net/manual/en/class.mysqli-driver.php
 *      http://php.net/manual/en/mysqli-driver.report-mode.php
 *      http://php.net/manual/en/mysqli.constants.php
 */
$mysqliDriver->report_mode = MYSQLI_REPORT_OFF;

答案 1 :(得分:0)

你的问题的答案很简单。如果(假设store_result()被调用),num_rows返回0,则表示您的查询未找到任何行。这很简单。无需寻找其他代码或责怪数据库。没有要获取的行?然后数据库中没有这样的数据。因此,要使您的查询返回确保 $_POST['username']包含数据库中存在的值所需的内容。

此外,我必须告诉你,这个函数/变量是mysqli(或任何其他数据库API)中最无用的部分。任何时候你需要它并且它可用,它可以用你已经拥有的其他东西代替。在您的情况下,您可以检查fetch()的结果,这将完美地用于此目的。

话虽如此,我有一种感觉,即使查询一切都很好,你的问题来自你正在使用的变量。您使用的是不存在的$ row变量,显然不返回任何内容。你有没有在PHP中使用正确的错误报告,它已经告诉过你了。因此,无论如何只记得正确处理错误,您可以参考我的文章PHP error reporting basics

所以,最后你的代码应该是这样的:

<?php

if (!isset($_POST['LOGIN'])){
    header("Location:index.php");
    exit;
}
require_once "condb.php";

$sql = "SELECT name,username,password,status FROM login WHERE username=?";
$stmt = $cn->prepare($sql);
$stmt->bind_param("s", $_POST['username']);
$stmt->bind_result($name,$username,$password,$status);
$stmt->execute();

if ($login->fetch() and password_verify($_POST['password'], $password) {
    if ($status=="Admin")
    {
        header("Location:admin/admin.php");
        exit();
    }
    echo "ok<br>You are $status!";
} else {
   echo "Username or password incorrect";
}

正如您所看到的,您的代码中还使用了一些其他无用的函数,我也删除了这些函数。你看,如果你只做它必须做的事情,PHP代码可以是紧凑和整洁的。

答案 2 :(得分:-1)

我写了一些适用于你的答案的内容,如下所示。

<?php
error_reporting(E_ALL);
require_once "condb.php";

if (!isset($_POST['LOGIN']))
{header("Location:index.php");}

else
{

  $username=$_POST['username'];
  $receivedpassword=$_POST['password'];
  $hashed_password=password_hash($receivedpassword,PASSWORD_DEFAULT);

  $login = $cn->prepare("SELECT name,username,password,status
                         FROM login 
                         WHERE username=?");

  $login->bind_param("s", $username);
  $login->execute();
  $login->store_result();
  $login->bind_result($name,$getusername,$getpassword,$status);
  $login->fetch();
  $count=$login->num_rows;

  echo $name."<br />".$getusername."<br />".$getpassword."<br />".
  $status."<br />".$count."<br />";
  var_dump($name);echo "<br />";
  var_dump($getusername);echo "<br />";
  var_dump($getpassword);echo "<br />";
  var_dump($status);echo "<br />";
  var_dump($count);echo "<br />";
  // start checking a row

  if($count > 0)
  { // start of username check

    echo 'You are going good of your username.'."<br />";

    if(password_verify($receivedpassword, $getpassword))
    { // start of pw check

      echo 'Your password is going good!'."<br />";

      //start to check permission
      switch ($status)
      {// start of switch
        case 'Admin':
          echo 'You are admin.';
          break;
        case 'Editor':
          echo 'You are editor.';
          break;
        case 'Author':
         echo 'You are author.';
         break;
        case 'User':
          echo 'You are user.';
          break;
        default:
          echo 'NO PERMISSION FOUND.';
          break;
      }// end of switch

    } // end of pw check

    // else from pw verify
    else
    { // check of incorrect password
      echo 'Your password isn\'t going good.';
    } // end of incorrect password check

  } // end of username check

  // else from $count > 0
  else
  {// No username found condition check

    echo 'Your username isn\'t going good.';

  } // end of no username found

}//end of everything

?>