前提・実現したいこと
PHPで、とあるウェブサイトを作っています。
ユーザー登録をして、その流れで登録後にログインをする仕組みにしているのですが、ログインできません。
登録する情報はusername,email,passwordで、ログインするときはusernameとemailの入力を求めます。
参考にしたサイトはドットインストールの
です。(プレミアム会員でないと閲覧できません)
こちらでは登録・ログインともにemailとpasswordだけだったのですが、usernameを追加して、ログインもemail→usernameに変えたところエラーが発生しました。
発生している問題・エラーメッセージ
Notice: Undefined index: username in /Applications/MAMP/~中略~/Model/User.php on line 23
User.php
<?php
namespace MyApp\Model;
class User extends \MyApp\Model {
public function create($values) {
$stmt = $this->db->prepare("insert into users (username, email, password, created, modified) values (:username, :email, :password, now(), now())");
$res = $stmt->execute([
':username' => $values['username'],
':email' => $values['email'],
':password' => password_hash($values['password'], PASSWORD_DEFAULT)
]);
if ($res === false) {
throw new \MyApp\Exception\DuplicateUsername();
}
}
public function login($values) {
$stmt = $this->db->prepare("select * from users where username = :username");
$stmt->execute([
':username' => $values['username']
]);
$stmt->setFetchMode(\PDO::FETCH_CLASS, 'stdClass');
$user = $stmt->fetch();
if (empty($user)) {
throw new \MyApp\Exception\UnmatchUsernameOrPassword();
}
if (!password_verify($values['password'], $user->password)) {
throw new \MyApp\Exception\UnmatchUsernameOrPassword();
}
return $user;
}
public function findAll() {
$stmt = $this->db->query("select * from users order by id");
$stmt->setFetchMode(\PDO::FETCH_CLASS, 'stdClass');
return $stmt->fetchAll();
}
}
index.phpの主要部分
<?php
// ログイン
require_once(__DIR__ . '/../config/config.php');
$app = new MyApp\Controller\Login();
$app->run();
// echo "login screen";
// exit;
?>
---
<form action="" method="post" id="login">
<p><input type="text" name="username" placeholder="username" value="<?= isset($app->getValues()->username) ? h($app->getValues()->username) : ''; ?>"></p>
<p><input type="password" name="password" placeholder="password"></p>
<p class="err"><?= h($app->getErrors('login')); ?></p>
<div class="btn" onclick="document.getElementById('login').submit();">Log In</div>
<p class="fs12"><a href="/signup.php">Sign Up</a></p>
<input type="hidden" name="token" value="<?= h($_SESSION['token']); ?>">
</form>
Login.php
<?php
namespace MyApp\Controller;
class Login extends \MyApp\Controller {
public function run() {
if ($this->isLoggedIn()) {
header('Location: ' . SITE_URL);
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$this->postProcess();
}
}
protected function postProcess() {
try {
$this->_validate();
} catch (\MyApp\Exception\EmptyPost $e) {
$this->setErrors('login', $e->getMessage());
}
$this->setValues('username', $_POST['username']);
if ($this->hasError()) {
return;
} else {
try {
$userModel = new \MyApp\Model\User();
$user = $userModel->login([
'password' => $_POST['password']
]);
} catch (\MyApp\Exception\UnmatchUsernameOrPassword $e) {
$this->setErrors('login', $e->getMessage());
return;
}
// login処理
session_regenerate_id(true);
$_SESSION['me'] = $user;
// redirect to home
header('Location: ' . SITE_URL);
exit;
}
}
private function _validate() {
if (!isset($_POST['token']) || $_POST['token'] !== $_SESSION['token']) {
echo "Invalid Token!";
exit;
}
if (!isset($_POST['username']) || !isset($_POST['password'])) {
echo "Invalid Form!";
exit;
}
if ($_POST['username'] === '' || $_POST['password'] === '') {
throw new \MyApp\Exception\EmptyPost();
}
}
}
宜しくお願い致します。
補足情報(言語/FW/ツール等のバージョンなど)
PHP5.6.10
データでベースに登録されていることは確認しました。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
エラーメッセージをよく読み、発生しているエラーについて確認してみましょう。
Notice: Undefined index: username in /Applications/MAMP/~中略~/Model/User.php on line 23
User.phpの23行目で定義されていない「username」インデックスを参照しているため、エラーになっているようです。該当箇所はuser#login()ですね。
user#login()を呼び出しているのはLogin.phpのpostProcess()ですが、呼び出す際のパラメータにて「password」しか渡していないようです。
「username」も必要であれば、一緒に渡すようにしてみましょう。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
ちょど面白い質問が建ってます。ご一読されてはいかがでしょうか。
ログインシステム(WEB) 自作?危険?セキュリティ対策は?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.31%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2016/05/05 09:50
回答ありがとうございます。
おっしゃられたようにやったところ、無事解決致しました。
「user#login()」というのはコードに書いていないのですが、何を指しているのでしょうか。
また、「user#login()を呼び出しているのはLogin.phpのpostProcess()ですが」
こちらはどの部分からそれが分かるんでしょうか。浅学でして、分かりません。これらも良ければ教えていただきたいです。
2016/05/05 09:58
Userクラスのloginメソッド、という意味で記載しました。分かりづらくてすみません。
> また、「user#login()を呼び出しているのはLogin.phpのpostProcess()ですが」
こちらはどの部分からそれが分かるんでしょうか。浅学でして、分かりません。これらも良ければ教えていただきたいです。
ログイン処理、ということでしたのでコントローラーである「Login.php」のメソッド「run()」から順に処理を追っていきました。
Login#run() -> Login#postProcess() -> User#login() といった具合です。
2016/05/05 10:22
いえ。当方初心者でして、業界ではそういったかたちで書くのだと勉強になりました。
> ログイン処理、ということでしたのでコントローラーである「Login.php」のメソッド「run()」から順に処理を追っていきました。
Login#run() -> Login#postProcess() -> User#login() といった具合です。
ご丁寧にありがとうございます。無事に理解できました。
また、宜しくお願い致します。