前回で、ユーザーデータの下準備が終わったので、今度はログインフォームの表示を作りましょう。index.phpと同じ階層にテンプレートをコピーして、login.phpを新たに作成していきましょう。完成イメージは下記の感じです。
login.php
<?php session_start(); | セッションを使った処理をする場合には、最初に左記のように冒頭に必ず宣言する必要があります。 |
if(isset($_SESSION[‘id’])){ header(‘Location: index.php’); } | isset関数により$_SESSION[‘id’]が存在していれば、TRUEと判断。ログインしていればログインフォームを表示する必要がないため、header関数でindex.phpへ移動させます。 |
else if (isset($_POST[‘name’]) && isset($_POST[‘password’] )){ $dsn = ‘mysql:host=localhost;dbname=baseball;charset=utf8’; $user = ‘baseballuser’; $password = ‘ ‘; //設定したパスワード | ログインしていない状態で、POSTメソッドでユーザー名とパスワードが送られてきた場合の処理です。 まず、データベース接続を行います。DSNとはData Source Nameの略でどのサーバーのどのデータベースを使うのかを指定します。 ‘mysql:host=ホスト名;dbname=DB名;charset=文字コード’; |
try { | try-catchの例外処理の構文です。エラーが起きた時の処理です。 発生しそうな処理をtryに入れて、その中で例外が発生した場合、catchに投げます |
$db = new PDO($dsn, $user, $password); | PDO(PHP Data Object)とはさまざまなデータベース(Oracle,SQLiteなど)でも同じ処理をできるようにするPHPの拡張機能。new演算子を使ってPDOクラスのインスタンスを作成。引数にDSN、ユーザー名、パスワードを必要とします。 |
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); | $dsにアロー演算子(->)によりsetAttributeメソッドを使うことでPDO設定を実行しています。次のプリペアードステートメントを使う際に、セキュリティを高めるための設定。 |
$stmt = $db->prepare(“SELECT * FROM users WHERE name=:name AND password=:pass”); | プリペアードステートメントとは、実行したい命令のテンプレートのようなもの。SELECT文はデータを取得する命令で、*と指定するとすべてのカラムを取得します。WHERE条件に名前が:name とパスワードが:passであるユーザーを検索するものです。 |
$stmt->bindParam(‘:name’, $_POST[‘name’], PDO::PARAM_STR); $stmt->bindParam(‘:pass’, hash(“sha256”, $_POST[‘password’]),PDO::PARAM_STR); | bindParamメソッドで:nameと:passに値を割り当てます。 :passへの割り当てのためのbindParamメソッドの第二引数は、ユーザーが送信したパスワードです。先般、データベースにデータを登録したとき、パスワードをSHA-256でハッシュ化しました。なので検索を行うときも、入力したパスワードをハッシュ化したものとマッチしないといけません。 |
$stmt->execute(); | クエリの実行 |
if($row = $stmt->fetch()){ $_SESSION[‘id’] = $row[‘id’]; header(‘Location: index.php’); exit(); | ユーザーが存在していたら、セッションにユーザーIDをセット。 |
}else { header(‘Location: login.php’); exit(); } } catch (PDOException $e){ exit(‘エラー:’ . $e->getMessage()); } } ?> | 結果セットからデータが取得できなかった場合は、ユーザー名・パスワードが間違っている可能性あり、header関数でもう一度ログインフォームを表示。 |
<!DOCTYPE html> <html lang=”ja”> <head> ~ | 省略していますが、bootstrapのCDNをheadタフ内に貼り付けて使用しています。 |
<style type=”text/css”> form{ width:100%; max-width:330px; padding:15px; margin:auto; text-align:center } #name { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } #password { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; } </style> </head> | ログインフォームのページ用にHTMLのheadタグ内部にスタイルを整えるためのCSSを記載します |
<body> <main role=”main” class=”container” style=”padding:60px 15px 0“> <div> <form action=”login.php” method=”post”> <h1>サークルサイト</h1> <label class=”sr-only“>ユーザー名</label> <input type=”text” id=”name” name=”name” class=”form-control” placeholder=”ユーザー名”> <label class=”sr-only“>パスワード</label> <input type=”password” id=”password” name=”password” class=”form-control” placeholder=”パスワード”> <input type=”submit” class=”btn btn-primary btn-block” value=”ログイン”> </form> </div> </main> </body> </html> | bootstrapのデザインを反映させるため太字のようにしています。 |