---
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 |
|:------------------------------------:|:------------------------------------:|
|  |  |
### 程式碼
```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">×</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資料表 |
|:------------------------------------------:|
|  |
### 要件
需要建立一個表格讓使用者輸入帳戶名稱。
| 創建頁面 |button備註 |
|:------------------------------------------:|:------------------------------------------ |
|  |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>
```