--- title: 筆記(八) 會員登入系統(上) tags: php,mysql --- ## 會員系統製作 製作一個會員系統,可以創建新帳戶,並且登入,可在個人空間編輯資料,修改密碼,然後登出。 > 首頁也跟是否有登入做出區別。 會用到的功能有: * 連結資料庫 * SESSION應用 * form表單 ### 連結php資料庫 > 參考網址:[w3school php MySQL Connect](https://www.w3schools.com/php/php_mysql_connect.asp) ```php= //connDB.php <?php //自訂時區 date_default_timezone_set("Asia/Taipei"); //DB connection $servername = "localhost"; $username = "mysql帳號"; $password = "mysql密碼"; $dbname = "資料庫名稱"; //create connection $conn = new mysqli($servername, $username, $password, $dbname); //check connection if($conn->connect_error){ die("Connection failed: " . $conn->connect_error); } //echo "Connect successfully"; //echo date("Y-m-d/H:i:s"); (這是西元年月日和當下時間) ?> ``` 建立好一個資料庫連結,之後需要用到時直接在該檔案上用 **include_once "connDB.php"** 就好了。 ### 流程 > [流程圖製作參考網址](https://hackmd.io/features-tw?both#UML-%E5%9C%96%E8%A1%A8) ```flow st=>start: 首頁 e=>end: 登出 op=>operation: 有無帳戶 op2=>operation: 登入 op3=>operation: 創建 op4=>operation: 進入個人空間 cond=>condition: 有或無? cond2=>condition: 是否登出? st->op->cond->op2->op3->op2->op4->cond2 cond(yes)->op2 cond(no)->op3 cond2(yes)->e cond2(no)->st ``` 已知需要做的有 * 首頁 * 登入modal * 判斷登入帳密是否正確 並且給予session * 創建帳戶 * insert創建時輸入的帳密 * 個人空間頁面 * 可供編輯資料 * 登出 * 登出時清除session ## 首頁 ### 元素 > 因為製作簡易的系統,所以首頁的主要目的是在於呈現是否有登入的樣子。 * 參考:[bootstrap v4.6 navbar](https://getbootstrap.com/docs/4.6/components/navbar/#supported-content) * 參考:[bootstrap v4.6 modal](https://getbootstrap.com/docs/4.6/components/modal/#examples) | 首頁 | 點擊 signin | |:------------------------------------:|:------------------------------------:| | ![](https://i.imgur.com/Oy3AXOh.png) | ![](https://i.imgur.com/VmZnO5W.png) | ### 程式碼 ```php //index.php <?php //尚未寫入 ?> <!doctype> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- 引入 Bootstrap --> ... </head> <body style="background-color:ADADAD"> //<!---navbar---> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Link</a> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-expanded="false"> Dropdown </a> <div class="dropdown-menu"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="#">Something else here</a> </div> </li> <li class="nav-item"> <a class="nav-link disabled">Disabled</a> </li> </ul> <a href="signin.php" class="btn btn-outline-success my-2 my-sm-0" type="button" data-toggle="modal" data-target="#staticBackdrop">sign in</a> </div> </div> </nav> <!-- Modal --> <div class="modal fade" id="staticBackdrop" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">登入</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <!---form---> <form> <div class="form-group"> <label for="Acc">Email address</label> <input type="text" class="form-control" id="Acc" aria-describedby="email"> </div> <div class="form-group"> <label for="Pass">Password</label> <input type="password" class="form-control" id="Pass"> </div> <button type="submit" class="btn btn-primary">Login</button> </form> <hr> <h5 class="text-center">還沒有帳戶?</h5> <div class="row justify-content-center"> <a href="createAcc.php" class="btn btn-success btn-lg" type="button"> Create </a> </div> </div> </div> </div> </div> </body> </html> ``` :::info 先將雛型用出來,暫不將一些複雜的設定寫入。 ::: ## 創建帳戶 > 帳戶創建需要將資料寫入資料庫,因此先在mysql建立一個名叫new的資料表,欄位如下。 > 之後會將資料insert進new資料表。 | new資料表 | |:------------------------------------------:| | ![](https://i.imgur.com/u0KONq2.png =80%x) | ### 要件 需要建立一個表格讓使用者輸入帳戶名稱。 | 創建頁面 |button備註 | |:------------------------------------------:|:------------------------------------------ | | ![](https://i.imgur.com/HU6WuJ2.png =70%x) |submit: 將表單送出<br>cancel: 取消創建帳戶,回首頁| ### 相關script :::warning 禁用Enter ::: 攸關於送出表單,先將enter按鍵關了才放心。 ``` <script language="javascript" type="text/javascript"> //禁用Enter document.onkeydown = function(event) { var target, code, tag; if (!event) { event = window.event; //for ie target = event.srcElement; code = event.keyCode; if (code == 13) { tag = target.tagName; if (tag == "TEXTAREA") { return true; } else { return false; } } } else { target = event.target; //for w3c code = event.keyCode; if (code == 13) { tag = target.tagName; if (tag == "INPUT") { return false; } else { return true; } } } }; </script> ``` :::warning 關於判斷密碼是否一致 ::: form表單的<input type="password">會讓使用者看不到輸入密碼,增加一個input來判斷兩者密碼是否一致,正確才送出。 ``` <!---pw define---> <script> function on_submit(){ var pwd = document.getElementById('inputPass'); var repwd = document.getElementById('rePass'); if(pwd.value != repwd.value){ alert('密碼不一致'); pwd.value = ""; repwd.value = ""; pwd.focus(); return false; } } </script> ``` ### 程式碼 ```php! //createAcc.php <?php session_start(); ?> <!doctype> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- 引入 Bootstrap --> //...skip <title>createAcc</title> //<!---pw define---> <script> function on_submit(){ var pwd = document.getElementById('inputPass'); var repwd = document.getElementById('rePass'); if(pwd.value != repwd.value){ alert('密碼不一致'); pwd.value = ""; repwd.value = ""; pwd.focus(); return false; } } </script> <script language="javascript" type="text/javascript"> //禁用Enter document.onkeydown = function(event) { var target, code, tag; if (!event) { event = window.event; //for ie target = event.srcElement; code = event.keyCode; if (code == 13) { tag = target.tagName; if (tag == "TEXTAREA") { return true; } else { return false; } } } else { target = event.target; //for w3c code = event.keyCode; if (code == 13) { tag = target.tagName; if (tag == "INPUT") { return false; } else { return true; } } } }; </script> </head> <body style="background-color:#ADADAD"> <div class="container"> <h6><br><br></h6> <h5 class="text-center">create account</h5> <div class="row justify-content-center"> <div class="col-12 col-md-6"> <!---form---> <form action="acc_update.php" onsubmit="return on_submit()" method="post"> <div class="form-group"> <label for="Acc">input Account</label> <input type="text" class="form-control" name="inputAcc" placeholder="account" required> </div> <div class="form-group"> <label for="Name">input Name</label> <input type="text" class="form-control" name="inputName" placeholder="name" required> </div> <!---pw---> <div class="form-group"> <label for="Pass">input Password</label> <input type="password" class="form-control" name="inputPass" id="inputPass" placeholder="password" required> </div> <div class="form-group"> <label for="rePass">verity Password</label> <input type="password" class="form-control" id="rePass" placeholder="password" required> </div> <button type="submit" class="btn btn-primary">Submit</button> <a class="btn btn-secondary" type="button" href="index.php">cancel</a> </form> </div> </div> </div> </body> </html> ``` :::info form表單裡輸入的input記得name要設定好,到時post到上傳頁面時用來接收的代號。 ::: ## insert進mysql ### 流程 ```flow st=>start: include_once "connDB.php" e=>end: 登出 op=>operation: 接收POST資料 op2=>operation: 密碼加密 op3=>operation: SQL INSERT op4=>operation: 判斷是否成功 st->op->op2->op3->op4->e ``` ### 程式碼 ```php! <?php session_start(); include_once "connDB.php"; //POST資料 $p_acc = addslashes($_POST["inputAcc"]); $p_name = addslashes($_POST["inputName"]); //hash password $p_pass = password_hash(addslashes($_POST["inputPass"]), PASSWORD_BCRYPT); $p_date = date("Y-m-d/H:i:s"); $add_sql = "INSERT INTO `new` (`account`, `password`, `name`, `date`) VALUES ( '$p_acc', '$p_pass', '$p_name', '$p_date' ) "; if($conn->query($add_sql) == true){ //echo 'successful!'; }else{ echo 'error: ' . $add_sql . "<br>" . $conn->error;; } ?> <!doctype> <html> <head> <!---copy---> <!---bootstrap---> </head> <body style="background-color: #ADADAD"> <h6><br><br><br><br></h6> <h5 class="text-center">創建成功!2秒後返回登入頁面...</h5> <?php exit(header("Refresh:2;url=index.php")); ?> </body> </html> ``` ## 附錄 每個網頁都有的一串cdn ```html! <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- 引入 Bootstrap --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <title>修改帳戶</title> </head> ```