1

SQLクエリから返された行を通過するwhileループがあります。その行の特定の列の値は配列に格納されます。次に、配列が繰り返され、各要素がユーザーからの入力と比較されます。入力が配列要素と一致する場合、ブール値はtrueになります。ユーザーが特定のページにアクセスするためのパスワードを入力できるように、これを実行しようとしています。しかし、それはうまくいきません。配列からのすべての値と入力を出力したので、そこに問題はないことがわかります。しかし、何らかの理由で、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

なぜforeachループなのですか?あなたはこのようにそれを行うことができます:

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

$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 に答える
0

提案:

1) mysql 関数の直接呼び出しを PDO に置き換えます: (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'])または$pwHash = sha1($_POST['pass'])任意の組み合わせを使用します。

4) コードを揃えてください。これにより、質問に答えてくれる人 (ヘルプを提供する) や、将来のメンテナンス (あなたや他の誰か; 信じてください。2、3 年でコードを忘れるでしょう) にとっても読みやすくなります。

5) あなたのコードは動作するはずですが、なぜ動作しないのかわかりません。var_dump を追加してみて$pw、パスワードが一致したときに画面に何かを書いてみてください。ページを交換した可能性があります (エラーのあるメンバー)

于 2012-11-17T14:26:27.677 に答える