PHP ログイン認証の作成手順④　〜ログイン機能作成①とセッションとキャッシュ〜

#ログイン機能の作成の流れ
①emailとpasswordを受け取る
②emailと一致するユーザ検索
③passwordが一致するか検証
④ユーザ情報をセッションに格納してログイン

#sessionとは
開始から終了までの期間のこと。
１ユーザのログインからログアウトまでの行動は１セッション。
１セッションはセッションIDで管理する。

通信(HTTP)はユーザを識別することができない。
そのため、識別するためにセッションが必要になる。
セッションIDを管理するのはCookie。

CookieはセッションIDをブラウザに保存する。

ユーザがログインすると、サーバ側からセッションIDが生成されてブラウザに送られ、Cookieに保存する。
そして、ログイン中は常にセッションIDを送って、サーバ側でユーザを識別してもらう。

##sessionの使い方
###関数
`session_start()`
→Cookie（ブラウザ）にセッションIDを入れる
→セッションファイルが生成される
→セッションファイルに自由に値を保存可能（現場ではセッションファイルを管理する用のデータベースを作ることが多い）

`session_destroy()`
→セッションファイルを削除する

###グローバル変数
`$_SESSION`
→セッションへデータを連想配列で保存

#ログインフォーム作成

```php:login.php
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ログイン画面</title>
</head>
<body>
    <h2>ログインフォーム</h2>
    <form action="top.php" method="POST">
    <p>
        <label for="email">メールアドレス：</label>
        <input type="email" name="email">
    </p>
    <p>
        <label for="password">パスワード：</label>
        <input type="password" name="password">
    </p>
    <p>
        <input type="submit" value="ログイン">
    </p>
    </form>
    <a href="signup_form.php">新規登録はこちら</a>
</body>
</html>
```

#バリデーションの作成
login.phpのsubmitでtop.phpに移動するのだが、移動した時のバリデーションを作成する

```php:top.php
<?php

require_once('../classes/UserLogic.php');

// エラーメッセージ
$err = [];

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

if(!$password = filter_input(INPUT_POST, 'password')){
    $err[] = 'パスワードを記入してください';
}

if(count($err) === 0){
    // ログインする処理
    echo 'ログインしました！';
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ登録完了画面</title>
</head>
<body>
<?php if (count($err) > 0) : ?>
<!-- エラーがある場合にforeachで該当エラーを表示させる -->
    <?php foreach($err as $e) : ?>
    <p><?php echo $e ?></p>
    <?php endforeach; ?>
<!-- $err配列に何もない＝エラーがない　から完了画面を表示させる -->
<?php else: ?>
    <p>ユーザー登録が完了しました。</p>
<?php endif ; ?>
<a href="login.php">戻る</a>
</body>
</html>
```

#sessionでバリデーションを出す
上記のやり方だと、top.php上でのエラー表示になる。
本来はlogin.phpでエラー表示をさせる。
そのためには、
①logion.php →　ログインフォームに入力して、ログインボタンを押す
②top.phpに移動して送られたデータのバリデーション行う
③header関数で強制的にlogin.phpへ戻して、sessionのデータを下にエラーを表示させる
という流れを作成する

保存されたsessionのデータはブラウザからも確認できるし、MAMP/tmp/phpフォルダの中にsessionファイルが作られており、その中にsessionの値が記述されている。

$_SESSION変数には`連想配列`として値が格納されることになる。

```php:top.php
<?php

require_once('../classes/UserLogic.php');

session_start();

// エラーメッセージ
$err = [];

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

if(!$password = filter_input(INPUT_POST, 'password')){
    $err['password'] = 'パスワードを記入してください';
}

if(count($err) > 0){
    // エラーがあった場合は戻す
    $_SESSION = $err;
    header('Location: login.php');
    return;
}
// ログイン成功時の処理
echo 'ログインしました！';
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザ登録完了画面</title>
</head>
<body>
<?php if (count($err) > 0) : ?>
<!-- エラーがある場合にforeachで該当エラーを表示させる -->
    <?php foreach($err as $e) : ?>
    <p><?php echo $e ?></p>
    <?php endforeach; ?>
<!-- $err配列に何もない＝エラーがない　から完了画面を表示させる -->
<?php else: ?>
    <p>ユーザー登録が完了しました。</p>
<?php endif ; ?>
<a href="login.php">戻る</a>
</body>
</html>
```

```php:login.php
<?php
session_start(); 

$err = $_SESSION;

// セッションを消す
$_SESSION = array();
session_destroy();
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ログイン画面</title>
</head>
<body>
    <h2>ログインフォーム</h2>
    <form action="top.php" method="POST">
    <p>
        <label for="email">メールアドレス：</label>
        <input type="email" name="email">
        <?php if(isset($err['email'])) : ?>
            <p><?php echo $err['email']; ?></p>
        <?php endif; ?>
    </p>
    <p>
        <label for="password">パスワード：</label>
        <input type="password" name="password">
        <?php if(isset($err['password'])) : ?>
            <p><?php echo $err['password']; ?></p>
        <?php endif; ?>
    </p>
    <p>
        <input type="submit" value="ログイン">
    </p>
    </form>
    <a href="signup_form.php">新規登録はこちら</a>
</body>
</html>
```