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

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

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1193閲覧

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

toll_tree

総合スコア199

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/04/26 05:03

編集2019/04/26 06:04

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

php

1<?php 2include 'shop_class.php'; 3$shop = new shop('mysql:host=localhost;dbname=ec_website','root','12345'); 4$err = []; 5 6 7if($_POST){ 8 $user_name = filter_input(INPUT_POST,'user_name'); 9 $password = filter_input(INPUT_POST,'password'); 10 11 if(!$user_name){ 12 $err[] = 'ユーザー名を入力してください'; 13 } 14 if(!$password){ 15 $err[] = 'パスワードを入力してください'; 16 } 17 18 19 if(!count($err) > 0){ 20 // var_dump($err); 21 // echo 'ng'; 22 // exit(); 23 24 $user_info = $shop->login_check($user_name); 25 26 if(count($user_info) > 0){ 27 28 if(password_verify($password,$user_info['password'])){ 29 echo 'top.phpへ遷移'; 30 //header('Location:top.php'); 31 exit(); 32 33 }else{ 34 $err[] = 'ユーザー名あるいはパスワードが違います'; 35 } 36 37 }else{ 38 $err[] = 'ユーザー名あるいはパスワードが違います'; 39 40 } 41 42 } 43 44} 45 46 47?> 48 49 50 51 52 53 54 55 56 57 58 59<!DOCTYPE html> 60<html lang="ja"> 61<head> 62 <meta charset="UTF-8"> 63 <link type="text/css" rel="stylesheet" href="./css/common.css"> 64 <title>user_regiseter</title> 65 66</head> 67<body> 68 <header class="header_box"> 69 <a href="user_register.php"> 70 <img class ="logo" src="./images/logo.png" alt="CodeShop"> 71 </a> 72 <a href="cart.php"> 73 <img src="./images/cart.png" alt="cart"> 74 </a> 75 </header> 76 77 <div class="content"> 78 79 <?php if($err):?> 80 <div class="check_msg"> 81 <?php foreach($err as $msg): ?> 82 83 <span class="err"><?=$msg;?></span> 84 85 <?php endforeach;?> 86 </div> 87 88 <?php endif;?> 89 90 91 <form class="form" method="post" action="login.php" > 92 <p><input type="text" name="user_name" placeholder="ユーザー名"></p> 93 <p>パスワード:<input type="password" name="password" placeholder="パスワード"></p> 94 <input type="submit" value="ログイン"> 95 </form> 96 97 <a class="login_link" href="user_register.php">ユーザー新規作成</a> 98 99 </div> 100 101</body> 102</html>

下記は、shop_class.phpです

php

1 2<?php 3 4class Shop 5{ 6 7 private $dbh; 8 9 public function __construct($dsn,$user,$password){ 10 $dbh = new PDO($dsn,$user,$password); 11 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 12 $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); 13 $this->dbh = $dbh; 14 } 15 16 public function h($str){ 17 return htmlspecialchars($str,ENT_QUOTES,'UTF-8'); 18 } 19 20 public function write($user_name,$password){ 21 22 $stmt = $this->dbh->prepare("INSERT INTO user(user_name,password,created_at)VALUES(:user_name,:password,now())"); 23 $stmt->bindValue(':user_name',$user_name,PDO::PARAM_STR); 24 $stmt->bindValue(':password',$password,PDO::PARAM_STR); 25 $stmt->execute(); 26 27 28 } 29 30 public function user_check($user_name){ 31 $stmt = $this->dbh->prepare("SELECT user_name FROM user WHERE user_name = :user_name"); 32 $stmt->bindValue(':user_name',$user_name,PDO::PARAM_STR); 33 $stmt->execute(); 34 $result = $stmt->fetchALL(PDO::FETCH_ASSOC); 35 if(count($result) > 0){ 36 return '同じユーザー名が既に登録されています'; 37 } 38 return 'ok'; 39 40 } 41 42 public function login_check($user_name){ 43 $stmt = $this->dbh->prepare(" SELECT user_name,password FROM user WHERE user_name = :user_name "); 44 $stmt->bindValue(':user_name',$user_name,PDO::PARAM_STR); 45 $stmt->execute(); 46 $user_info = $stmt->fetchALL(PDO::FETCH_ASSOC); 47 return $user_info; 48 49 } 50 51}
以下はエラーの内容になります。 「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" } }」 です。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

質問に$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']ですよね?

PHP

1 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'を指定しパスワードハッシュの値を取得するところ)で「そんなもの無いよ」と通知されています。

PHP

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

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

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

PHP

1 $user_info = $shop->login_check($user_name); 2 var_dump($user_info); 3 4 if(count($user_info) > 0){ 5 6 var_dump($user_info); 7 if(password_verify($password,$user_info['password'])){

投稿2019/04/26 05:11

編集2019/04/26 06:08
Y.H.

総合スコア7914

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toll_tree

2019/04/26 05:23

ご回答ありがとうございます。 本文にも追記しましたが、$user_infoの「password」キーは存在しているんですよね...
m.ts10806

2019/04/26 05:33

Y.H.さん 行内に入れたいならバッククォート1つですね。 あああ`ここに文字`ああああ
Y.H.

2019/04/26 05:34

でも$user_info['password']は無いとPHPは判断しています。 追記に記載したvar_dump()の結果を質問に追加ください。
Y.H.

2019/04/26 05:35

...orz ありがとう>mts10806さん
toll_tree

2019/04/26 05:55

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

2019/04/26 06:03

回答に追記しました
toll_tree

2019/04/26 06:21

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

0

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

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

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

投稿2019/04/26 05:16

編集2019/04/26 06:18
m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toll_tree

2019/04/26 05:24

そうですね。 一応、追記しました。
m.ts10806

2019/04/26 05:29

「ある」だけではなんとも言えません。var_dumpの結果をそのまま提示してください。 それか、shop_class.phpのコードも追記するのでも良いです。
m.ts10806

2019/04/26 05:59 編集

先んじて回答追記してますが、追記した内容で当たりですね。階層が違います。 login.php側を修正というより$shop->login_check()で返却するデータを1件だけにしたほうがトラブルが少なくなります。
toll_tree

2019/04/26 06:19

多次元配列なのに、気づきませんでした... shop_class.phpも追記しました。 login_checkメソッドで、 「$user_info = $stmt->fetchALL(PDO::FETCH_ASSOC);」 「return $user_info;」 としていますが、これだと、配列そのものを返すことになってしまい、結果的に、配列に値を返すと、多次元配列になってしまうのですね...
m.ts10806

2019/04/26 06:23

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

2019/04/26 07:00

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問