ログイン機能作成 PHP

#■①ユーザーテーブルの定義
●データ名：user
●テーブル名:users

カラムは4つにする。

| カラム | タイプ | 長さ |照合順序|INDEX|A_I|
|:-:|:-:|:-:|:-:|:-:|:-:|
| id | INT |  ||PRIMARY|☑️|
| name | VARCHAR | 64 |utf8mb4_unicode_ci|
| email | VARCHAR| 191 |utf8mb4_unicode_ci|UNIQUE|
| password | VARCHAR | 191 |utf8mb4_unicode_ci|

テーブル 照合順序 utf8mb4_unicode_ci

実行で作成。

###▼データ接続の権限を追加
●権限をクリック
●一番したの[ユーザーを追加]をクリック
下記4つを入力
username
Hostname 練習中はlocalを選ぶ
Password
Password再入力

●ユーザアカウント専用データベース
データベース user へのすべての権限を与える。のチェックマークをはずす。

●データと構造にチェックマークで操作の権限を与える。
●実行

#■②PHPでデータ接続
●env.phpにデータ接続で使う道具をまとめる。

``` env.php

<?php
 define('DB_HOST','localhost');
 define('DB_NAME','データ名');
 define('DB_USER','権限で作ったuser名');
 define('DB_PASS','権限で作ったpassword');
?>
```
●dbconnect.phpで実際にデータを接続する

``` dbconnect.php
<?php
  require_once('env.php');
  //エラーが出た時エラー内容を表示してくれる。
  ini_set('display_errors',true);
  //DB接続メソッドを作成
  function connect() {
  //env.phpで作ったDB接続道具を変数に!
  $host = DB_HOST;
  $db   = DB_NAME;
  $user = DB_USER;
  $pass = DB_PASS;
  
  $dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4";
  try { $pdo = new PDO($dsn,$user,$pass,
               //エラーのモードを決める。
              [PDO::ATTR_ERRMODE => ERRMODE_EXCEPTION,
              //配列をキーと値で返す。
               PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC])
       echo '成功です。'
     }catch(PDOExeption $e) {
       echo '接続失敗です。'. $e->getMessage();
     }
  }
?>
```


#■③ ユーザー登録の画面を作る。

``` signup_form.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザー登録画面</title>
</head>
<body>

//下記を作成
  <form action='register.php' method='post'>
   <p>
   <label for="username">名前:</label>
   <input type='text' name='username'>
   </p>
   <p>
   <label for="email">メールアドレス:</label>
   <input type='email' name='email'>
   </p>
   <p>
   <label for="password">パスワード:</label>
   <input type='password' name='password'>
   </p>
   <p>
   <label for="password">パスワード確認:</label>
   <input type='password' name='password_conf'>
   </p>
 </form>

</body>
</html>
```

#■④ バリデーション
ユーザーが記載した情報が正しいか確認する事
正しくなかった場合はエラーメッセージを記載。

■filter_input(INPUT_POST,'postで渡ってくるname');
ifと組み合わせるとpostで指定したname属性の中身が存在するかわかる。
postで指定したname属性の中身の事

■正規表現
指定した表現つまり英単語の指定文字数の指定　指定した表現になっているかチェック。
preg_match("/\A[a-z\d]{8,100}+\z/i",'チェックしたいname')
上記なら英単語かつ8文字以上100文字以内ですと指定してる。

``` register.php
<?php
 //エラー出た時のメッセージを入れる空の配列を用意
 $err = [];

if(!$username = filter_input(INPUT_POST,'username')) {
  $err[] = '名前を記入してください。';
}

if(!$email = filter_input(INPUT_POST,'email')) {
  $err[] = 'メールアドレスを記入してください。';
}

$pass = filter_input(INPUT_POST,'password');
if(!preg_match("/\A[a-z\d]{8,100}+\z/i",$pass)) {
  $err[] = 'パスワードは英単語で8文字以上100文字以下にしてください。';
}

$pass_conf = filter_input(INPUT_POST,'pass_conf');
if($pass != $pass_conf) {
 $err[] = '確認用パスワードと異なっています。';
}

if(count($err) === 0) {
 //エラーが0ならここで登録処理をしていきます。
 //後で登録処理のクラスを作っていきます。
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザー登録完了画面</title>
</head>
<body>
//もしエラー内容が配列$errにあれば表示
<?php if(count($err)>0):?>
<?php foreach($err as $e):?>
<p><?php echo $e:?></p>
<?php endforeach?>
<?php else:?>
//エラー内容がなければ登録完了です。
<p>登録完了です。</p>
<?php endif?>
<a href="./signup_form.php">
</body>
</html>
```

#■⑤クラス作成 データ登録

```UserLogic.php
<?php
 require_once('dbconnect.php');

class UserLogic {

  /**下記のようにどんなメソッドか説明しておくと分かりやすい。
  *ユーザー登録する。
  *@param array $userData
  *@return bool $result
  */
  
  //staticにするとクラスに紐づく 呼び出し方も変わる。
  public static function createUser($userData) {
    //データの登録
    $sql = 'INSERT INTO users(name,email,password) VALUES(?,?,?)';

   $arr = [];
   $arr[] = $userData['username'];
   $arr[] = $userData['email'];
   //パスワードのハッシュ化これでパスワードが見えなくなる。
   $arr[] = password_hash($userData['password'],PASSWORD_DEFAULT);
  
  try{
  $stmt = connect()->prepare($sql);
  //引数に$arrを入れるとsql文の?,?,?に$arrが入る。
  $result = $stmt->execute($arr);
  return $result;
  } catch(\Exception $e) {
    return $result;
  }
}
?>
```

#■⑥ バリデーションのエラーが0だった時にデータ登録メソッドを通す。

``` register.php
<?php
 //エラー出た時のメッセージを入れる空の配列を用意
 $err = [];

if(!$username = filter_input(INPUT_POST,'username')) {
  $err[] = '名前を記入してください。';
}

if(!$email = filter_input(INPUT_POST,'email')) {
  $err[] = 'メールアドレスを記入してください。';
}

$pass = filter_input(INPUT_POST,'password');
if(!preg_match("/\A[a-z\d]{8,100}+\z/i",$pass)) {
  $err[] = 'パスワードは英単語で8文字以上100文字以下にしてください。';
}

$pass_conf = filter_input(INPUT_POST,'pass_conf');
if($pass != $pass_conf) {
 $err[] = '確認用パスワードと異なっています。';
}

if(count($err) === 0) {
  UserLogic::createUser($_POST);
　　　 if(!$hasCreated) {
        $err[] = "登録に失敗しました";
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザー登録完了画面</title>
</head>
<body>
//もしエラー内容が配列$errにあれば表示
<?php if(count($err)>0):?>
<?php foreach($err as $e):?>
<p><?php echo $e:?></p>
<?php endforeach?>
<?php else:?>
//エラー内容がなければ登録完了です。
<p>登録完了です。</p>
<?php endif?>
<a href="./signup_form.php">
</body>
</html>
```