:::
9-1 改寫 login()
一、改寫login()
- 原理說明:
- 先過濾並檢查變數(帳號)
- 拿帳號(email)到資料庫取抓取資料
- 若有,比對密碼是否正確,若正確,寫入session(包括姓名、群組、Email、編號)
- 若無,則登入失敗。
- 重新改寫login()變成資料庫版:
//登入 function login() { global $db; $email = $db->real_escape_string($_POST['email']); if (empty($email)) { throw new Exception("Eamil為必填!"); } $email = filter_var($email, FILTER_VALIDATE_EMAIL); if (!$email) { throw new Exception("不合法的Email"); } $pass = isset($_POST['pass']) ? $_POST['pass'] : ''; $sql = "SELECT * FROM `users` where `email`='{$email}'"; $result = $db->query($sql); if (!$result) { throw new Exception($db->error); } $data = $result->fetch_assoc(); if (password_verify($pass, $data['pass'])) { $_SESSION['group'] = $data['group']; $_SESSION['name'] = htmlspecialchars($data['name'], ENT_QUOTES); $_SESSION['uid'] = $data['uid']; $_SESSION['email'] = htmlspecialchars($data['email'], ENT_QUOTES); } else { throw new Exception("登入失敗!"); } } - 一樣先整理輸入的Email
- 利用email為唯一值的特性,讀取屬於該帳號的所有身家資料(且預計只會有一筆)。
- 利用 $result->fetch_assoc() 取出資料陣列,並存入$data中以便取用。其中,$data的陣列內容類似這樣:
- $data['uid']=1;
- $data['name']='tad';
- $data['email']='tad@tn.edu.tw';
- $data['pass']='xxxxx';
- $data['group']='admin';
- 若是改用 $result->fetch_row() 取出資料陣列,$data的陣列內容則類似這樣(通常會搭配 list() 一起使用):
- $data[0]=1;
- $data[1]='tad';
- $data[2]='tad@tn.edu.tw';
- $data[3]='xxxxx';
- $data[4]='admin';
- 利用 password_verify($pass, $data['pass']) 來檢查密碼是否正確
- 若正確,定義$_SESSION['group'] 及 $_SESSION['name'] 等值,表示登入。
- 若不正確,則丟出異常訊息。
二、修改登出
- 既然登入紀錄的東西已經不一樣,登出也要跟著改
//登出 function logout() { unset($_SESSION['group']); unset($_SESSION['name']); unset($_SESSION['uid']); unset($_SESSION['email']); }
三、練習:
- 請把要存入資料庫的值過濾、檢查部份寫成函數 clean_var(),並放到function.php中,以簡化程式。例如:
$name = $db->real_escape_string($_POST['name']); if (empty($name)) { throw new Exception("姓名為必填!"); } $email = $db->real_escape_string($_POST['email']); if (empty($email)) { throw new Exception("Eamil為必填!"); } $email = filter_var($email, FILTER_VALIDATE_EMAIL); if (!$email) { throw new Exception("不合法的Email"); } $pass = $db->real_escape_string($_POST['pass']); if (empty($pass)) { throw new Exception("密碼為必填!"); }可簡化為
$name = clean_var('name', '姓名'); $email = clean_var('email', 'Eamil', FILTER_VALIDATE_EMAIL); $pass = clean_var('pass', '密碼'); -
參考答案:
//檢查並傳回欲拿到資料使用的變數 function clean_var($var = '', $title = '', $filter = '') { global $db; $clean_var = $db->real_escape_string($_REQUEST[$var]); if (empty($clean_var)) { throw new Exception("{$title}為必填!"); } if ($filter) { $clean_var = filter_var($clean_var, $filter); if (!$clean_var) { throw new Exception("不合法的{$title}"); } } return $clean_var; }
9. 從資料庫中讀取資料的方法