1

我有一个遍历从 SQL 查询返回的行的 while 循环。该行中特定列的值存储在数组中。然后遍历数组,并将每个元素与用户的输入进行比较。如果输入与数组元素匹配,则布尔值变为真。我正在尝试这样做,以便用户可以输入密码来访问特定页面。然而它只是行不通。我已经打印了数组中的所有值以及输入,所以我知道那里没有问题。但由于某种原因,if 语句不会比较它们。这是代码:

if (isset( $_POST['ok'])) {
  $password = $_POST['pass'];
  $matched = false;
  $pw = array();
  mysql_connect("localhost", "xxx", "xxx")or die("Error");
  mysql_select_db("details")or die("Error");
  $query="SELECT * FROM members";
  $result=mysql_query($query);
  while ($row = mysql_fetch_assoc($result) ){
    $pw[] = $row["pass"];
  }
  foreach($pw as $p){
    if(strcmp($p, $password) == 0){
      $matched = true;
    }
  }
  if ($matched==true) {
    //Membership page
  } else {
    //Error message
  }
} else {
  ....
4

4 回答 4

1

将您的查询更改为这样的内容会更容易和更有效

$dbh = mysql_connect("localhost", "xxx", "xxx") or die("Error");
mysql_select_db("details", $dbh ) or die("Error");

$pass = mysql_real_escape_string( $_POST['pass'], $dbh );
$user = mysql_real_escape_string( $_POST['user'], $dbh );

$sqlQuery = <<< EOQ
    SELECT
        *
    FROM
        `members`
    WHERE
        `user` COLLATE utf8_bin = '{$user}' COLLATE utf8_bin
        AND
        `password` COLLATE utf8_bin = '{$pass}' COLLATE utf8_bin
EOQ;

$result = mysql_query( $sqlQuery );
if ( $result and ( mysql_num_rows( $result ) === 1 ) {
       echo "success";
       $userDetails = mysql_fetch_assoc( $result );
} else {
       echo "username or password wrong";
}

编辑:将密码和用户名检查更新为在任何情况下都区分大小写

Edit2:以上评论提醒不要存储明文密码。更改为散列密码

UPDATE members SET pass = SHA1( pass );

然后将您的支票更改为

... AND pass = SHA1( '{$pass}' )
于 2012-11-17T14:19:59.883 回答
0

Why the foreach loop ? You can do it like this:

if (isset( $_POST['ok'])) {
  $password = $_POST['pass'];
  $matched = false;
  $pw = array();
  mysql_connect("localhost", "xxx", "xxx")or die("Error");
  mysql_select_db("details")or die("Error");
  $query="SELECT * FROM members";
  $result=mysql_query($query);
  while ($row = mysql_fetch_assoc($result) ){
    $pw[] = $row["pass"];
  }
   $pw_tmp = flip_array($pw);

   if(isset($pw_tmp[$password])){
      //Membership page
   }else{
      //Error message
   }
}else{
  // something else ...
}
于 2012-11-17T14:38:51.003 回答
0

建议:

1)用PDO替换直接的mysql函数调用:(这不需要任何转义,因为PDO会处理所有事情)

$mysql_host = "localhost";
$mysql_user = "xxx";
$mysql_password = "xxx";
$mysql_database = "details";
$dbLink = new PDO("mysql:host=$mysql_host;dbname=$mysql_database;charset=utf8", $mysql_user, $mysql_password, array(PDO::ATTR_PERSISTENT => true));
$query = db()->prepare("select * from members WHERE pass = ? limit 1");
$query->execute(array($_POST['pass']));
$query->setFetchMode(PDO::FETCH_ASSOC);
$myMember = $query->fetch();
$query->closeCursor();

2)如果您想坚持使用您的代码,您可以使用$pwd = mysql_real_escape_string($_POSt['pass'])发布的密码,然后选择包含转义接收密码的行$pwd。另外,不要忘记mysql_free_result($result);

3) 对密码进行哈希处理,因此您不需要使用 mysql_real_escape_string。使用$pwHash = md5($_POST['pass'])or$pwHash = sha1($_POST['pass'])或任何组合。

4)请对齐您的代码。它将使回答您的问题(提供帮助)的人以及将来的维护(您或其他人;相信我,您会在 2-3 年内忘记代码)更具可读性。

5)你的代码应该可以工作,我不知道为什么它不工作。尝试添加 var_dump for$pw并在密码匹配时在屏幕上写一些东西。也许您交换了页面(有错误的成员)

于 2012-11-17T14:26:27.677 回答
0

找到匹配项后需要休息一下,以便 $matched 等于 true。

if ( isset( $_POST['ok'] ) ) {

$password = $_POST['pass'];
$matched = false;
$pw = array();

mysql_connect("localhost", "xxx", "xxx")or die("Error");
mysql_select_db("details")or die("Error");
$query="SELECT * FROM members";
$result=mysql_query($query);

while ($row = mysql_fetch_assoc($result) ){
$pw[] = $row["pass"];
}

foreach($pw as $p){
  if(strcmp($p, $password) == 0){
  $matched = true;    // found match so break out and do the membership.
  break;
}
}

    if ($matched==true) {

      //Memebrship page

    } else {

      //Error message
    }

} else {

....
于 2012-11-17T14:19:22.793 回答