各位大大您好:
我試寫一個登入頁面,若輸入正確帳號密碼跟驗證碼,會顯示'已成功',但是只要有輸入錯誤,並不會跳到else 顯示'失敗',會是在'資料庫已成功開啟'畫面,想請問要怎麼修改呢? 謝謝
以下是登入頁面html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>鑰匙管理系統</title>
</head>
<body>
<center>
<p>鑰匙管理系統</p>
<form name="form1" action="key_login.php" method="post">
姓名:<input type="text" name="name"><br>
<br>
密碼:<input input type="password" name="id"> <br>
<br>
驗證碼:<input type="number" name="ans"><img src="testpic.php" width="35" height="25" alt="show image"><br>
<p><input type="submit" value="送出"><input type="reset" value="重新設定" name="reset"></p>
</form>
</center>
</body>
</html>
以下是key_login.php
<?php session_start(); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>PDO</title>
</head>
<body>
<?php
$hostdb='localhost';
$namedb='key';
$userdb='root';
$passdb='123!';
/*try { */
$conn= new PDO("mysql:host=$hostdb;dbname=$namedb",$userdb,$passdb);
echo'資料庫已成功開啟'.'<br>';
$conn->exec("SET CHARACTER SET utf8");
/*}
catch(PDOEXception $e){
echo $e->getMessage();
}*/
$name=$_POST['name'];
$id=$_POST['id'];
$sql="SELECT name,pw FROM admin where name='$name'and pw='$id'";
$result = $conn->query($sql);
foreach ($result->fetchALL() as $row)
{
if ($name!=null && $id=!null && $row['name']==$name && $row['pw']==$id && $_POST['ans']==$_SESSION['test'])
echo '已成功';
else
echo '失敗';
}
$conn=null;
?>
</body>
</html>
登入不是這樣判斷的,如果 $result
沒有查到資料,foreach
就不會執行
$result = $conn->query($sql);
foreach ($result->fetchALL() as $row)
{
if ($name!=null && $id=!null && $row['name']==$name && $row['pw']==$id && $_POST['ans']==$_SESSION['test'])
echo '已成功';
else
echo '失敗';
}
先不管你程式裡的漏洞,要修正也很簡單,改成這樣
if(!empty($result->fetchALL())
echo '已成功';
else
echo '失敗';
還有其他問題:
$name!=null && $id=!null
應該在你去資料庫查詢前就檢查$id=!null
prepare
可以將 SQL 語法與參數分開處理來避免攻擊,但你用法錯了"SET CHARACTER SET utf8"
,建議用 "SET NAMES 'UTF8'"
,原因:https://stackoverflow.com/a/1566908"mysql:host=$host;dbname=$db;charset=utf8"
最後在你搞懂與修正 SQL Injection 之前,不要讓你寫的網站上線運作
在你搞懂與修正 SQL Injection 之前,不要讓你寫的網站上線運作
在你搞懂與修正 SQL Injection 之前,不要讓你寫的網站上線運作
w大您好:
我大概有修正如下變數前加addslashes跟SQL變數改問號,這樣是否不會產生SQL Injection 謝謝
$name=addslashes($_POST['name']);
$id=addslashes($_POST['id']);
$sql="SELECT name,pw FROM admin where name= ? and pw= ?";
$result = $conn->prepare($sql);
$result->execute(array($name,$id));
$result1=$result->fetch(PDO::FETCH_OBJ);
if ($result1&&$_POST['ans']==$_SESSION['test'])
現在沒人那樣做了, 去把 prepare 搞懂吧, 學一次可以用很久, 不要再花時間去學過時的東西
隨手改一改給你參考, 但不保證能跑:
$name = filter_input(INPUT_POST, 'name');
$id = filter_input(INPUT_POST, 'id');
$sql="SELECT name,pw FROM admin WHERE name=:name AND pw=:pw";
$sth = $conn->prepare($sql);
$sth->execute([':name' => $name, ':pw' => $id]);
if ($sth->rowCount() > 0) {
$result=$sth->fetch(PDO::FETCH_OBJ);
if ($result && $_POST['ans'] === $_SESSION['test'])
w大您好:
看到您改的了~謝謝~
要怎麼google呢?(我自己google都是以前的做法,買書也沒特別寫到這塊)因為我也不是本科出生..只是有興趣寫看看 謝謝
這本是必讀: http://www.books.com.tw/products/0010688181
剩下的就只能多關注新消息, 參加社群或是各個研討會
有些可以線上看的, 例如 https://www.youtube.com/user/PHPSrbijaVideo/videos
去社群裡找個家教或許是最快的方式
w大我再請教一個問題
:pw(這是甚麼意思)跟$pw(知道是變數)是差在哪呢,:pw綁定參數嗎?可是為什麼不直接寫$pw謝謝~
你原本的 prepare
是用 ?
來標示參數的位置,然後再按照陣列的順序去填,所以你參數一多就連帶要常常確認順序對不對。
$sth->execute(['參數1', '參數2', '參數3']);
:name
是另一種用法,等於是給參數標上名稱,這樣就會以名稱來帶入參數
$sth->execute([':name' => '參數1', ':phone' => '參數3', ':email' => '參數2']);
通常用名稱來標示會更好讀一些,但這是 pdo 才有的功能。如果你有機會用到 mysqli_
系列的函式,他只支援 ?
這種形式綁定參數。