ここではログイン/ログアウト画面を作成しましょう!
ただし、ログイン、ログアウトは処理としていささか複雑です。
そのため、まずはサンプルを丸写ししましょう。
その上で、解説を読みながら、それぞれがどういった動きをしているのか確認してください。
余裕がある方は、2回目、3回目と書き写し、最終的には何も見ずに書けると良いですね。
(任意です。)
サンプルソース
login.phpサンプル
main.phpサンプル
logout.phpサンプル
ログイン画面、ログイン処理
さて、ソースコードを写し終え、4-1フォルダに配置できれば、http://localhost/LetsEngineer/curriculum/4-1/login.php
にアクセスし、下のように表示されるはずです。
また、名前とパスワードを空欄にしてログインボタンを押せば、エラーメッセージが表示されます。
(まだちょっと無愛想ですが。)
それではソースコードを見ながら、特徴的なメソッドを確認していきましょう。
値が空であることを確認するempty
ユーザー名やパスワードが空欄であったならば 、気の利いたメッセージでも出力したいですよね?
下記のコードがそれに該当します。
// ログイン名が入力されていない場合の処理 if (empty($_POST["name"])) { echo "名前が未入力です。"; } // パスワードが入力されていない場合の処理 if (empty($_POST["pass"])) { echo "パスワードが未入力です。"; }
POSTで送信されたname
、pass
がそれぞれ空であった場合(未入力だった場合)、メッセージを表示させています。
empty
というのが とある変数や値が空でないかチェックするメソッド です。
公式リファレンス-empty-
また、逆に 空でない場合 をチェックするとき、!empty
とビックリマークをつけることで対応できます。
!
は「 〜でなかったら 」を短く表すことに使用します。
!empty($_POST))
のように使用して、 POSTされたデータが空でない場合 といった具合に使用します。
HTML文字をエスケープするhtmlspecialchars
さて、POSTされたname
とpass
が空欄でなければ、いよいよ処理開始です。
ただ、空でなくてもまだ注意する箇所があります。
例えば、入力フォームで下記のようにHTMLタグを埋め込んだ場合、何も対策をしていなければ、 そのHTMLが意味を持ってしまいます 。
例えばフォームに入力した内容を取得するでやったような簡単なプログラムを例にします。
このレッスンでは、何も対策をしていません。
名前欄に<h1>yoneyama</h1>
と入力して送信します。
このように、h1タグ
が意味を持ってしまい、ビューの表示を変えてしまいます。
このようなことへの対策として、htmlspecialchars
というメソッドがPHPには用意されています。
先ほどの例も、h1タグ
を単なる文字列と認識してくれます。
このような処理を エスケープ と言います。
ログインのサンプルソースでは、下記で使用しています。
//ログイン名とパスワードのエスケープ処理 $name = htmlspecialchars($_POST['name'], ENT_QUOTES); $pass = htmlspecialchars($_POST['pass'], ENT_QUOTES);
$_POST['name']
、もしくは$_POST['pass']
をエスケープします。
第2引数のENT_QUOTES
ですが、こちらはオプションでいくつか種類があります。
とりあえず、htmlspecialchars
を使用するときにはENT_QUOTES
を指定し、慣れてきたらコンテンツに合わせて変えていきましょう。
公式リファレンス-htmlspecialchars-
結果が1行取得できたら。。。
DBにSELECT文で検索をかけ、結果が取得できました。
ユーザー名に一致する人がいればデータがあるはずです。
データを連想配列で取得する場合は、$stmt->fetch(PDO::FETCH_ASSOC)
でしたね。
ただ、PDO実装ではwhile
を使用していたのに対し、今回はif
を使用しています。
本来、fetch
は先頭1件しか取得してきません。
ただし、ループ文(while
のような)を使用することで、 複数の結果を順番に1行ずつ読み込んでくれます 。
今回はユーザーの結果は1件だけあれば良いので、先頭1件のみ取得しています。
そもそもユーザー名が間違っていた場合、$row = $stmt->fetch(PDO::FETCH_ASSOC
がFALSE
で返るため、条件文を満たしません。
はじめは難しいので、このような書き方として覚えましょう。
パスワードの確認を行うpassword_verify
さて、新規登録画面の際にパスワードはハッシュ化して登録していました。
POSTされたデータと、DBから取得したハッシュ化されたパスワードで比較するため、password_verify
メソッドを使用します。
- 第1引数:ハッシュ化されていないパスワード($_POST[‘pass’])
- 第2引数:ハッシュ化されているパスワード($row[‘password’]、今回で言えばDBに保存されているデータ)
// ハッシュ化されたパスワードを判定する定形関数のpassword_verify // 入力された値と引っ張ってきた値が同じか判定しています。 if (password_verify($pass, $row['password'])) {
この条件文を満たすのであれば、ログイン成功とします。
セッションについて
さて、文頭、およびログイン成功時の処理で下記のような文章があるかと思いますが、こちらは次項で解説します。
// セッション開始 session_start();
// セッションに値を保存 $_SESSION["user_id"] = $row['id']; $_SESSION["user_name"] = $row['name'];
ログイン成功したら、main.phpに移動
ログイン成功したら、ログインページに用はありません。
さっさとmain.php
を表示させたいです。
今回はheader
関数を利用して、ログイン成功したら強制的にmain.php
に移動させます。
// main.phpにリダイレクト header("Location: main.php");
本来header
関数は他の意味がありますが、header("Location: hogehoge.php")
と、Location
を入れることで、特定のページに移動させることができます。
公式リファレンス-header-
このように強制的にページを移動させることを リダイレクト と言います。
今後、このリダイレクト処理を実装したい場合は、上記のソースで言えばmain.php
のファイル名を編集すれば、そのファイルにリダイレクトさせることができます。
ちなみにこのheader関数の注意点については こちら にまとめてありますので、目を通すようにしておいてください。
メインページ
メインページについては、今回簡素な作りとなっています。
また、セッションに関する説明は次項に回したいと思います。
ただ、ログアウトしやすいようにリンクだけ作っておきます。
<a href="logout.php">ログアウト</a>
ログアウト画面、ログアウト処理
ログアウト処理についても、キモとなるのはセッションです。
そのため、本項での解説は省略します。
再度ログインしやすいように、ログインのリンクは作っておきましょう。
<a href="login.php">ログイン画面に戻る</a>