最初に,データベース接続用の dbconnect.php とログイン画面 index.php を作成します。ここではまだ common/common.php は使いません。
source_dbconnect/dbconnect.php
<?php
// dbconnect.php
// 第5章前半で使用するPDO版データベース接続ファイル
$dsn = 'mysql:host=localhost;dbname=challenge;charset=utf8mb4';
$user = 'root';
$password = '';
try {
$dbh = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
} catch (PDOException $e) {
exit('データベース接続に失敗しました。');
}
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION を指定しておくと,SQLや接続に失敗したときに例外として扱えるため,問題箇所を見つけやすくなります。
source_dbconnect/index.php
<?php
// index.php: ログイン画面
session_start();
require_once __DIR__ . '/dbconnect.php';
function h($value): string
{
return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
}
$error = '';
if (!empty($_POST)) {
if ($_POST['mail'] !== '' && $_POST['pass_word'] !== '') {
$sql = 'SELECT * FROM member WHERE mail = :mail';
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':mail', $_POST['mail'], PDO::PARAM_STR);
$stmt->execute();
$record = $stmt->fetch();
if ($record && password_verify($_POST['pass_word'], $record['pass_word'])) {
$_SESSION['id'] = $record['id'];
$_SESSION['time'] = time();
header('Location: top_page.php');
exit();
}
$error = 'メールアドレスまたはパスワードが間違っています。';
} else {
$error = 'メールアドレスとパスワードを入力してください。';
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"><title>ログイン</title></head>
<body>
<h1>ログイン</h1>
<?php if ($error !== ''): ?><p style="color:red"><?php echo h($error); ?></p><?php endif; ?>
<form action="" method="post">
<p>メールアドレス:<input type="email" name="mail" required></p>
<p>パスワード:<input type="password" name="pass_word" required></p>
<p><input type="submit" value="ログイン"></p>
</form>
<p><a href="entry.php">ユーザー登録</a></p>
</body>
</html>
ログイン処理では,メールアドレスだけで会員情報を取得し,取得できたレコードに対して password_verify() を使ってパスワードを照合します。SQL文にはプレースホルダ :mail を使い,利用者が入力した値をSQL文字列へ直接連結しません。