iT邦幫忙

0

於PHP設login session時,找不到資料時為何無法顯示錯誤訊息?

各位高手們好:
最近剛開始學程式,在試著從資料庫抓資料寫入SESSION時,出現了我不知該如何檢測排除的錯誤:
即資料庫有找到資料時,程式可正確顯示"使用者EMAIL,歡迎光臨。"
但,資料庫沒找到資料時,畫面卻只顯示一片空白(本預期該顯示帳密錯誤)。
不知道有沒有人可以給我一點提示怎樣查問題 ?
無論結果如何,都十分感激 ~

謝謝

<?php  
session_start();
include '../common/config.php';
include '../common/define.php';
include '../common/utility.php';

$ss_role_id = isset($_POST["u_role_id"]) ? $_POST["u_role_id"] : "";  
$ss_u_email = isset($_POST["u_email"]) ? $_POST["u_email"] : "";
$ss_u_password = isset($_POST["u_password"]) ? $_POST["u_password"] : "";

$pdo = db_open();

// 寫 SQL 語法
$sqlstr = "SELECT u_email, u_password, u_role_id, uid, u_fname FROM users WHERE u_email=? and u_password=? and u_role_id='2' ";
$sth = $pdo->prepare($sqlstr);
$sth->bindValue(1, $ss_u_email, PDO::PARAM_STR);
$sth->bindValue(2, $ss_u_password, PDO::PARAM_STR);

if($sth->execute())
{
   // 成功執行 query 指令
   //$total_rec = $sth->rowCount();
   $ss = '';
   $msg ='';
   $html = '';
   $ss_uid ='';
   while($row = $sth->fetch(PDO::FETCH_ASSOC))
   {
      $ssdb_u_email = convert_to_html($row['u_email']);
      $ssdb_u_password = convert_to_html($row['u_password']);
      $ssdb_u_role_id = convert_to_html($row['u_role_id']);
      $ssdb_uid = convert_to_html($row['uid']);
      $ssdb_u_fname = convert_to_html($row['u_fname']);

	   // echo $ssdb_u_email;
	   // echo $ssdb_u_password;
	   // echo $ssdb_uid;
	   // echo $ssdb_u_fname;	   
	   // exit;

	    $valid = false; 		
	  	if($ssdb_u_email==$ss_u_email && $ssdb_u_password==$ss_u_password && $ssdb_u_role_id=='2')
		{

		   $valid = true;
		   $_SESSION["u_role_id"] = $ssdb_u_role_id;
		   $_SESSION["u_email"] = $ssdb_u_email;
		   $_SESSION["u_password"] = $ssdb_u_password;
		   $_SESSION["uid"] = $ssdb_uid;
		   $_SESSION["u_fname"] = $ssdb_u_fname;
		   //$msg = $ss_u_email . ' 帳密正確你好,歡迎光臨! '; 
		   echo $ss_u_email . ' 帳密正確你好,歡迎光臨! ';
		   exit;
		}
		else
		{  
	 	//這區判斷秀不出來!!!
		echo 'x'; 
		   // $_SESSION["u_role_id"] = '';
		   // $_SESSION["u_email"] = '';
		   // $_SESSION["u_password"] = '';
		   // $_SESSION["uid"] = '';
		   // $_SESSION["u_fname"] = '';
		   //$msg = '登入錯誤';
		echo  ' 帳密錯誤! ';
		exit;
		}
    }	

}
else
{
   // 無法執行 query 指令時
   $html = error_message('list_all');
   echo $sqlstr;
}

include '../web/pagemake.php';
pagemake($html, ''); 
?>
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
James
iT邦大師 6 級 ‧ 2018-01-30 15:25:11

大致看起來,好像沒找到資料就不會進到while迴圈。

suellen iT邦新手 5 級 ‧ 2018-02-01 06:18:07 檢舉

Dear LKK:
十分感謝,問題解決了,
查了點資料,又多懂點點PDO的運作邏輯/images/emoticon/emoticon07.gif

1

其實是因為你將判斷寫在需要找到資料裏面。找不到資料的情況下。就會從
while($row = $sth->fetch(PDO::FETCH_ASSOC))
這段跳開了。
自然你其下的未找到判斷就不會運行了

其實你那段判斷可以放到while後處理。
如果沒找到你的 $ssdb_uid 的話。那就是登入不正常。

suellen iT邦新手 5 級 ‧ 2018-02-01 06:20:57 檢舉

Dear yoching:
非常謝謝詳細的解說,問題解決了 :D
查了點資料,又多懂點點PDO的運作邏輯,感恩 /images/emoticon/emoticon07.gif

1
wiseguy
iT邦超人 1 級 ‧ 2018-01-31 10:58:04

編輯 php.ini 這個設定檔,找到底下兩個設定值

display_errors = ...
error_reporting = ...

設定值前面如果有 ; 把它拿掉。display_errors 如果 = Off 就改為 = On。
重新 restart apache (如果裝 apache php module) 或是 restart php-fpm (如果裝 php fastcgi)。
這樣你 php 錯誤時,就會秀在畫面上了。之後發佈到正式站台,記得再改為 Off,以免錯誤訊息外洩給 user/hacker 知道。

suellen iT邦新手 5 級 ‧ 2018-02-01 06:40:38 檢舉

Dear wiseguy,

十分謝謝,已開啟,相信對未來除錯有幫助 /images/emoticon/emoticon07.gif

2
Ray
iT邦大神 1 級 ‧ 2018-01-31 21:04:46

只有我覺得這隻程式會是個大災難嗎?....

(萬一資料庫裡有數百萬個會員的話)

看更多先前的回應...收起先前的回應...
suellen iT邦新手 5 級 ‧ 2018-02-01 06:46:06 檢舉

謝謝您。不好意思~剛入門新手 /images/emoticon/emoticon16.gif
請問是sql查詢的問題嗎?
在基礎知識不是很扎實的情況下,會建議怎樣改進呢?

無論如何都十分謝謝

Ray iT邦大神 1 級 ‧ 2018-02-01 09:23:04 檢舉

這不能怪你, 畢竟有很多東西, 要實際看過別人寫的, 才知道原來可以這樣用? 而且從程式的邏輯看來, 您可能還沒學過 SQL 語法....

先給您一個方向:

有沒有辦法不要用迴圈 (While) 的方式, 只下一個 SQL 指令, 就能比對出登入資料是否正確?

這個問題可能會花您幾個月的時間去思考, 不過, 如果有機會閱讀別人寫的程式時, 您很快就會知道答案.....

這個答案應該會有兩個階段的優化:

第一個階段就如前面所述, 先將 while 迴圈去掉, 只用一個 SQL 指令來解決, 這樣你的程式就不需要跑上百萬次, 只為了去找一個 User 的登入資料;

第二個階段優化比較困難, 必須了解先 DB 的運作原理, 基本方向是: 想辦法讓上面那個比對登入資料的單一 SQL 指令, 不要引起 DB 的 Table scan 行為.

解決這兩個問題之後, 不管你要比對上百萬, 上千萬個用戶, 速度都是一瞬間就完成了....(不然 Facebook 怎麼來得及比對用戶的登入? 他有 20 億筆耶...)

我不會寫程式, 沒辦法給您範例, 這裡有很多 SQL 高手, 他們應該可以提供很多建議....但是我負責管系統和 Infra, 從經驗就一眼看出, 這隻程式會在我的系統內翻雲覆雨犯眾怒, 肯定會被我抓出來鞭....

別讓這件事困擾您太久, 因為自己想, 不太容易想得出來, 需要很多外來的啟發, 您就把這個問題放在心裡, 以後有機會遇到類似情境時, 順便拿出來想一想, 或跟人一起討論, 有一天靈光一閃, 就通了....

有空可以看看 SQL 語法...

fillano iT邦超人 1 級 ‧ 2018-02-01 11:33:40 檢舉

其實你的sql語法跟你的php程式判斷是重複的...已經用email, password, role當作where條件查詢資料,那資料庫只會吐給你符合條件的結果,並不需要在php又判斷一次。

在這裡用while語法是合理的,主要是pdo並不會知道查詢結果有幾筆。(也可以改用fetchAll)但是如果資料庫設計沒問題的話,下這樣的sql語法,應該只會產生0或1筆結果。

簡單的判斷:如果查詢無結果,你就知道登入失敗了。查詢結果有一筆,那就是登入成功。查詢結果超過一筆...那你資料庫設計有問題XD

Ray iT邦大神 1 級 ‧ 2018-02-01 12:33:33 檢舉

大師出馬果然.....

我沒有看到最前面的 SQL command (大概是螢幕太扁了...), 以為只用了後面的 while 指令而已, 所以誤判了您的做法, 大師的說法正確, 在此向各位說聲抱歉...
/images/emoticon/emoticon13.gif

suellen iT邦新手 5 級 ‧ 2018-02-06 18:28:06 檢舉

非常謝謝 raytracy 與 fillano 與兩位高手的指導,我知道還有非常多的基礎知識需要學習與熟悉。
這幾天又練習寫了幾隻程式,約略懂了重覆的意思及修改的方式,我會再調整,讓程式減少不必要多餘的判斷,藉此更熟悉pdo一點。

非常謝謝大家的指導與幫忙~謝謝 /images/emoticon/emoticon07.gif

我要發表回答

立即登入回答