---
# System prepended metadata

title: 筆記(八) 會員登入系統(上)
tags: [mysql, php]

---

---
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>
```