質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.58%

Noticeエラーが発生してしまいます

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 822

score 35

password_verifyによる認証に失敗してしまった場合、Noticeエラーが出てしまいます。今までは、認証に失敗してもNoticeエラーとはならず、falseとなるだけでした。Noticeエラーが出てしまう、理由が分からないため、ご教示頂ければ幸いです。
該当のコードは、以下のlogin.phpです。

<?php
include 'shop_class.php';
$shop = new shop('mysql:host=localhost;dbname=ec_website','root','12345');
$err = [];


if($_POST){
  $user_name = filter_input(INPUT_POST,'user_name');
  $password = filter_input(INPUT_POST,'password');

  if(!$user_name){
    $err[] = 'ユーザー名を入力してください';
  }
  if(!$password){
    $err[] = 'パスワードを入力してください';
  }


  if(!count($err) > 0){
    // var_dump($err);
    // echo 'ng';
    // exit();

    $user_info = $shop->login_check($user_name);

    if(count($user_info) > 0){

        if(password_verify($password,$user_info['password'])){
        echo 'top.phpへ遷移';
        //header('Location:top.php');  
        exit();

      }else{
        $err[] = 'ユーザー名あるいはパスワードが違います';  
      }

    }else{
      $err[] = 'ユーザー名あるいはパスワードが違います';

    }

  }

}


?>











<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link type="text/css" rel="stylesheet" href="./css/common.css">
  <title>user_regiseter</title>

</head>
<body>
  <header class="header_box">
    <a href="user_register.php">
      <img class ="logo" src="./images/logo.png" alt="CodeShop">
    </a>
    <a href="cart.php">
      <img src="./images/cart.png" alt="cart">
    </a>
  </header>

  <div class="content">

      <?php if($err):?>
        <div class="check_msg">
          <?php foreach($err as $msg): ?>

            <span class="err"><?=$msg;?></span>

          <?php endforeach;?>
        </div>

        <?php endif;?>


    <form class="form" method="post" action="login.php" >
      <p><input type="text" name="user_name" placeholder="ユーザー名"></p>
      <p>パスワード:<input type="password" name="password" placeholder="パスワード"></p>
      <input type="submit" value="ログイン">    
    </form>

    <a class="login_link" href="user_register.php">ユーザー新規作成</a>

  </div>

</body>
</html>


下記は、shop_class.phpです

<?php

class Shop
{

  private $dbh;

  public function  __construct($dsn,$user,$password){
    $dbh = new PDO($dsn,$user,$password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
    $this->dbh = $dbh;
  }

  public function h($str){
    return htmlspecialchars($str,ENT_QUOTES,'UTF-8');
  }

  public function write($user_name,$password){

    $stmt = $this->dbh->prepare("INSERT INTO user(user_name,password,created_at)VALUES(:user_name,:password,now())");
    $stmt->bindValue(':user_name',$user_name,PDO::PARAM_STR);
    $stmt->bindValue(':password',$password,PDO::PARAM_STR);
    $stmt->execute();


  }

  public function user_check($user_name){
    $stmt = $this->dbh->prepare("SELECT user_name FROM user WHERE user_name = :user_name");
    $stmt->bindValue(':user_name',$user_name,PDO::PARAM_STR);
    $stmt->execute();
    $result = $stmt->fetchALL(PDO::FETCH_ASSOC);
    if(count($result) > 0){
     return '同じユーザー名が既に登録されています'; 
    }
    return 'ok';

  }

  public function login_check($user_name){
    $stmt = $this->dbh->prepare(" SELECT user_name,password FROM user WHERE user_name = :user_name ");
    $stmt->bindValue(':user_name',$user_name,PDO::PARAM_STR);
    $stmt->execute();
    $user_info = $stmt->fetchALL(PDO::FETCH_ASSOC);
    return $user_info;

  }

}
以下はエラーの内容になります。
「Notice: Undefined index: password in C:\xampp\xampp\htdocs\ec_website\login.php on line 28」

追記です。$user_infoの中身なのですが、$user_info = $shop->login_check($user_name);ここの時点では、キー「password」及び「user_name」は存在しています。

追記です。


$user_info = $shop->login_check($user_name);
var_dump($user_info);

if(count($user_info) > 0){

var_dump($user_info);
if(password_verify($password,$user_info['password'])){
```
上記の、「$user_info」の返り値は、上から、「array(1) { [0]=> array(2) { ["user_name"]=> string(7) "yamada1" ["password"]=> string(60) "$2y$10$wVmi2NTWAK857dsfUTIG1O5r0krEMP2m1yfVH6MXva1XJbJbtH3my" } }」

その下のvar_dumpの結果は、「array(1) { [0]=> array(2) { ["user_name"]=> string(7) "yamada1" ["password"]=> string(60) "$2y$10$wVmi2NTWAK857dsfUTIG1O5r0krEMP2m1yfVH6MXva1XJbJbtH3my" } }」
です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+3

質問に$user_infoのvar_dump結果が追加されたのを受けて追記

array(1) { [0]=> array(2) { ["user_name"]=> string(7) "yamada1" ["password"]=> string(60) "$2y$10$wVmi2NTWAK857dsfUTIG1O5r0krEMP2m1yfVH6MXva1XJbJbtH3my" } }」

ありませんね、$user_info['password']。あるのは、$user_info[0]['password']ですよね?

    if(password_verify($password,$user_info[0]['password'])){

とするか $shop->login_check($user_name) の戻り値の返し方を変更してください。

今までは、認証に失敗してもNoticeエラーとはならず、falseとなるだけでした。

メソッドlogin_check()をなんか変更しませんでした?


提示のNOTICEは$user_infoにキーpasswordが無いという通知です。$shop->login_check($user_name)で返されるArrayを確認しましょう。
としか回答しようがないです。


追記:

今までは、認証に失敗してもNoticeエラーとはならず、falseとなるだけでした

認証まで行ってません。認証はpassword_verify()でされますが、password_verify()の第2引数に指定する値を取得するところ($user_infoからキー'password'を指定しパスワードハッシュの値を取得するところ)で「そんなもの無いよ」と通知されています。

    if(password_verify($password,$user_info['password'])){

追記です。$user_infoの中身なのですが、$user_info = $shop->login_check($user_name);ここの時点では、キー「password」及び「user_name」は存在しています。

以下のように、2か所にvar_dump($user_info);を入れて出力された内容を質問に記載ください。

    $user_info = $shop->login_check($user_name);
    var_dump($user_info);

    if(count($user_info) > 0){

        var_dump($user_info);
        if(password_verify($password,$user_info['password'])){

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/26 14:55

    追記ありがとうございます。
    結果を、本文に追記しました

    キャンセル

  • 2019/04/26 15:03

    回答に追記しました

    キャンセル

  • 2019/04/26 15:21

    多次元配列だったんですね...
    ともあれ、訳が分からなかったので、解決でき、助かりました。

    キャンセル

0

質問前にできることはたくさんあります。

追記されたので追記:
var_dumpの結果をそのまま提示されるか、shop_class.phpのコードを追記されないと何とも言えませんが
多次元配列で返ってきてるのではないかと推測。
[0]=>['username'=>'hogehoge','password'=>'hogehoge']

var_dump()の結果による追記:
login.php側を修正というより$shop->login_check()で返却するデータを1件だけ(多段配列にすらしない)
にしたほうがトラブルが少なくなります。
認証関係の処理なのに複数件返す可能性があるっておかしいですし。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/26 15:23

    関数名は大文字小文字大別しないのでトラブルになっていませんが、なるべくPHPマニュアルからコピペするくらい慎重にやってください。
    https://www.php.net/manual/ja/pdostatement.fetchall.php
    ※EclipseなどのIDEですと候補がでてくるので間違えることは少なくなります。
    fetchAll()は検索結果など、1件だけではない処理について利用するのが有用です。
    1件のみ引っ張ってくると保証されているなら(PKのみの検索)fetchでじゅうぶんです。

    キャンセル

  • 2019/04/26 16:00

    fetchAllでとってきた際は、多次元配列になったのですが、fetch(PDO::FETCH_ASSOC)として、返したら、多次元配列ではなくなっていました。
    fetchAllは多次元配列として、返すというのが、少し、注意しておかないとならない点ですね...

    キャンセル

  • 2019/04/26 16:02

    PHPマニュアルを読めば理解できるところだと思います。
    https://www.php.net/manual/ja/pdostatement.fetch.php
    >PDOStatementオブジェクトに関連付けられた結果セットから1行取得します。
    1行なので多次元ではありません。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る