PHP入門 | ページ遷移、Cookie、セッション | セッションを使ったログイン

それでは実際にセッションを使ってみよう。ここでは、セッション利用の基本中の基本と言えるログイン機能を実装してみる。正式にユーザー名とパスワードをデータベースに保存して、というところまではまだ少し大変なので、まずはPHPスクリプト内にそれらの値を変数として用意し、それと照合するだけにしてみよう。

ここでは、ログインページのindex.phpと、ログインしたときに表示されるindex2.phpの2ページを作る。まずログインページであるindex.phpから、次のようにコードを書く。

<?php
    @session_start();
     
    if ($_POST != null){
        $account = $_POST['account'];
        $pass = $_POST['pass'];
        $_SESSION['account'] = $account;
        $_SESSION['pass'] = $pass;
        header("Location: ./index2.php");
    }
?>
<!DOCTYPE html>
<html lang="ko">
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
        <title>sample page</title>
    </head>
    <body>
        <h1>Hello PHP!</h1>
        <p>
            <?php
            if (isset($_SESSION['account'])) {
                echo "your account:" . htmlspecialchars($_SESSION['account']);
            }   
            ?>
        </p>
        <hr>
        <form method="post" action="./index.php">
            ACCOUNT :<input type="text" name="account"><br>
            PASSWORD:<input type="password" name="pass"><br>
            <input type="submit" value="移動">
        </form>
        <hr>
    </body>
</html>

ここでフォームを送信すると、先頭のスクリプトでその内容を確認し、セッションへ保存している。これ自体はログインチェックをしているわけではない。単に送信されたアカウントとパスワードを保存しているだけである。

最初にsession_startを実行しており、その前に@が付いている。これは以前ファイルアクセスのときに登場した、「エラーが発生しても無視して続行する」ためのものである。サーバーによってはセッション機能が標準でONになっている場合もあり、そのような場合に再度セッションを開始しようとすると「すでに開始している」というエラーが発生することがある。そのための予防措置である。

$account = $_POST['account'];
$pass = $_POST['pass'];
$_SESSION['account'] = $account;
$_SESSION['pass'] = $pass;

セッション関係の処理は非常に簡単である。$_SESSIONに保存すればすべて保存される。ほかに説明がいらないほど単純だ。もう1つ触れておくなら、現在のアカウントを表示しているbody内のスクリプト部分である。ここでは次のように書かれている。

if (isset($_SESSION['account'])) {...中略...

issetという関数は、引数に指定した変数が存在するかどうかを確認する。つまりこれは、$_SESSION['account']があるかどうかを確認しているのである。

ログインしているときだけページを表示する

続いてindex2.phpを書いてみよう。ここではログインされているかをチェックし、ログインしているときだけページを表示するようにする。例のコードは次のように書けばよい。

<?php
    @session_start();
     
    // ACCOUNTとPASS
    $ok_account = "admin";
    $ok_pass = "kanri";
     
    // ログインチェック
    $flg = false;
    $account = $_SESSION['account'];
    $pass = $_SESSION['pass'];
    if ($account == $ok_account and $pass == $ok_pass){
        $flg = true;
    }
    // ログインしていないときの処理
    if (!$flg){
        echo "<html><body><h1>NOT LOGIN!!!</h1>";
        echo '<a href="./index.php">back to login page.</a>';
        echo "</body></html>";
        exit;
    }
?>
<!DOCTYPE html>
<html lang="ko">
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
        <title>sample page</title>
    </head>
    <body>
        <h1>Index2.php!</h1>
        <p>[Account: <?php echo htmlspecialchars($account); ?>]</p>
        <p>新しく用意されたページです。</p>
        <hr>
    </body>
</html>

ここではまず@session_startした後、登録ユーザーのアカウントとパスワードを$ok_account$ok_passに用意しておく。そして$_SESSIONからaccountpassの値をそれぞれ取り出し、値を確認して、アカウントとパスワードが合っていれば$flgという変数にtrueを代入している。これはログイン成功かどうかを示す変数で、これがtrueならログイン済み、falseならログインしていないということになる。

ログインしていない場合は、echoでエラーメッセージとindex.phpへ戻るリンクを表示し、最後にexitしている。これは「ここでスクリプトの実行を終了する」という意味である。exitを実行すると、それ以降のコードはすべて実行されない。PHPスクリプトだけでなく、後に書かれているHTMLコードもすべて出力されない。つまり、ログインしていなければ、ここに含まれるページ自体が表示されない。

ここではechoでエラーを書き、exitを実行することで対応したが、方法はいろいろある。エラーページへリダイレクトしたり、ログインページへ戻したりしてもよいだろう。このほかにもさまざまな方法を考えてみてほしい。

ログインチェックの一般化

これで、ログインしているときだけページを表示する処理はできた。しかし、すべてのページにここに書いたような処理を書かなければならないとしたら、ログインチェックは非効率である。このような場合には、ログインチェック用のページを用意し、それを各ページで読み込んで実行するようにできる。

次の簡単な例を見てみよう。

check.phpのコード

<?php
    @session_start();
     
    // ACCOUNTとPASS
    $ok_account = "admin";
    $ok_pass = "kanri";
     
    // ログインチェック
    $flg = false;
    $account = $_SESSION['account'];
    $pass = $_SESSION['pass'];
    if ($account == $ok_account and
            $pass == $ok_pass){
        $flg = true;
    }
    // ログインしていないときの処理
    if (!$flg){
        echo "<html><body><h1>NOT LOGIN!!!</h1>";
        echo '<a href="./index.php">back to login page.</a>';
        echo "</body></html>";
        exit;
    }
?>

check.phpを利用したページ例

<?php include_once('./check.php'); ?>
<!DOCTYPE html>
<html lang="ko">
    <head> 
        <meta http-equiv="Content-Type"  content="text/html; charset=UTF-8" /> 
        <title>sample page</title>
    </head>
    <body>
        <h1>Index2.php!</h1>
        <p>[Account: <?php echo htmlspecialchars($account); ?>]</p>
        <p>新しく用意されたページです。</p>
        <hr>
    </body>
</html>

ここではcheck.phpというファイルをindex.phpなどと同じ場所に作成し、そこにログインチェック処理を用意する。そして、ログインチェックを必要とするページ、たとえばindex2.phpには、次の1文を先頭に書いておく。

<?php include_once('./check.php'); ?>

たったこれだけで、そのページはログインしていなければ見ることができなくなる。ここではinclude_onceという関数を使っている。これは引数に指定したスクリプトファイルを1回だけ読み込む機能を持つ。check.phpを取り込むと、その場でスクリプトが実行されるため、ここでログインしていなければエラーが表示され、exitが実行される。当然、このページのinclude_once以降の内容も表示されない。

 

ログインシステムの基本は、これでおおよそわかったはずである。この後は、アカウントとパスワードをよりしっかり管理する仕組みを考えていけば、それなりに使えるログインシステムを作れるだろう。