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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

Q&A

解決済

3回答

1282閲覧

password_verify関数を使い、入力したパスワードとデータベースのパスワードを比較したい

freemac

総合スコア29

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

0グッド

0クリップ

投稿2020/02/26 02:51

編集2020/02/26 08:03

ボールドテキスト### password_verify関数を使い、認証システムを作りたい
phpファイルで作業し、パスワード認証システムを実装中にエラーが出力されました。

発生している問題・エラーメッセージ

Notice: Trying to access array offset on value of type bool in /Applications/MAMP/htdocs/templates/login.php on line 12

該当のソースコード

login.php

PHP

1<?php 2ini_set('display_errors', 1); 3error_reporting(E_ALL); 4session_start(); 5$loginerror['vali']=""; 6require('join/dbconnect.php'); 7if(!empty($_POST)){ 8try{ 9 $member1 = $db->prepare('SELECT * FROM members where email=?'); 10 $member1->execute(array($_POST['email'])); 11 $result = $member1->fetch(); 12 if(password_verify($_POST['password'],$result['password'])){ 13 header('Location: index.php'); 14 exit(); 15 } 16} 17 catch(PDOException $e){ 18 print('db接続エラー' . $e->getMessage()); 19 } 20?> 21 22<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 23<html xmlns="http://www.w3.org/1999/xhtml"> 24<head> 25<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 26<link rel="stylesheet" type="text/css" href="style.css" /> 27<title>ログインする</title> 28</head> 29 30<body> 31<div id="wrap"> 32 <div id="head"> 33 <h1>ログインする</h1> 34 </div> 35 <div id="content"> 36 <div id="lead"> 37 <p>メールアドレスとパスワードを記入してログインしてください。</p> 38 <p>入会手続きがまだの方はこちらからどうぞ。</p> 39 <p>&raquo;<a href="join/">入会手続きをする</a></p> 40 </div> 41 <form action="" method="post"> 42 <input type="hidden" name="action" value="submit" /> 43 <dl> 44 <dt>メールアドレス</dt> 45 <dd> 46 <input type="text" name="email" size="35" maxlength="255" value="" /> 47 </dd> 48 <dt>パスワード</dt> 49 <dd> 50 <input type="password" name="password" size="35" maxlength="255" value="" /> 51 </dd> 52 <dt>ログイン情報の記録</dt> 53 <dd> 54 <input id="save" type="checkbox" name="save" value="on"> 55 <label for="save">次回からは自動的にログインする</label> 56 <?php if($loginerror['vali'] === 'blank'):?> 57 <p class="error">メールアドレスとパスワードを入力してください></p> 58 <?php endif;?> 59 60 ?> 61 </dd> 62 </dl> 63 <div> 64 <input type="submit" value="ログインする" /> 65 </div> 66 </form> 67 </div> 68 <div id="foot"> 69 <p><img src="images/txt_copyright.png" width="136" height="15" alt="(C) H2O Space. MYCOM" /></p> 70 </div> 71</div> 72</body> 73</html> 74

dbconnect.php

PHP

1<?php 2try{ 3 $db = new PDO('mysql:dbname=mini_bbs;host=127.0.0.1;charset=utf8', 'root', 'root'); 4 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 5}catch(PDOException $e){ 6print('db接続エラー' . $e->getMessage()); 7} 8 9?>

試したこと

password_verify関数の部分が原因ということで、Qiita等で調べると、スカラー型変数に配列アクセスするとこのようなエラーが出ると書いてありました。しかし、$_POST,$resultはどちらも連想配列の扱いで、正当にアクセスしているように思えます。何か誤っている点がありましたら、ご教授お願いしたいです。アドバイスのもと、try-catchを使用しましたが、db側からのエラーの返答はない状態です。

追記

fetchメソッドがfalseを返す場合を考慮して、if文で検証したのちにpasswoed_verify関数を使うことで入力したパスワード、データベースのパスワードを比較できました。

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

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

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

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

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

guest

回答3

0

ベストアンサー

$_POST,$resultはどちらも連想配列の扱いで

PDOのfetchは、失敗した場合にFALSEを返します(PHPマニュアル)。

投稿2020/02/26 02:53

maisumakun

総合スコア146018

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

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

freemac

2020/02/26 03:00 編集

失敗した場合にはfalseを返し、成功した場合は連想配列が返り値となるということですね。 $_POSTも同じ形式の返り値でないと比較対象にできない、ということでしょうか。
退会済みユーザー

退会済みユーザー

2020/02/26 04:12

実質 if(password_verify($_POST['password'],FALSE)){ で動くと思う? って言いたいんだと察した。 そもそもpassword_verify()なんぞにFALSEを与えないよう、直前にfetch()が成功したかどうかを検証するべきなんじゃないかと。 (言わなくてもわかるよね?ってところまで察したけど、伝わったかどうかは・・)
freemac

2020/02/26 04:17

伝わりました!返り値の確認を怠らないようにします。アドバイスありがとうございました。
guest

0

何か誤っている点が

DBはPHPなどのアプリケーション側からすると外部の仕組みなのでDB側でエラーがあったとしてもそのままでは詳細拾えません。

try-catchでPDOExceptionを捕捉するようにしてください。
つまりエラーハンドリングないのが間違いです。

例え接続時のみに施していたとしても、一度接続してしまえばネットワークエラー関係以外で落ちることはそうそうなく、外部からの入力を受け付けることもあるSQL実行時のほうが圧倒的にエラーとなる可能性が高いためです。

投稿2020/02/26 03:07

m.ts10806

総合スコア80875

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

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

freemac

2020/02/26 03:09

なるほど!アドバイスありがとうがざいます。try-catchでdb側の詳細も拾えるように変更します。
退会済みユーザー

退会済みユーザー

2020/02/26 03:56

join/dbconnect.php でのDB接続部分で、例外スローするように記述していないと、意味ないですけどね。
freemac

2020/02/26 04:03

既にdbconnect.phpの方では例外スローするようにしていました!
m.ts10806

2020/02/26 04:16

と書かれても「調べました」だけ言ってるのと同じですよ。 「望ましい実装をしているか」が課題なので、実装されたコードが全てです。
guest

0

password_verify関数の部分をif($result!==false)で実行するとエラーが消えました。返り値の確認を怠らないように作業しようと思います!

投稿2020/02/26 04:16

freemac

総合スコア29

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

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

m.ts10806

2020/02/26 04:18 編集

エラーが消えることだけを目的にしては同じレベルの質問を繰り返し同じ指摘を受け続けることになるだけです。今回のタイトルは何を達成したいためにつけたのですか? 低評価しました。
freemac

2020/02/26 04:57 編集

password_verify関数を使い、入力したパスワードとデータベースのパスワードが一致を確認するシステムを作りたいといった目的です。自分としては、エラーの記述部分を改善すれば正常に機能すると考え、エラーの理由を追跡することが第1ステップだと考え、質問をさせていただいた次第です。返り値を逐一確認することも覚えようと思いました。エラーが消えることだけを目的にすること→同じレベルに留まり続ける、というのは少し違和感を感じます。 経験が浅い上に長文で失礼しました。
退会済みユーザー

退会済みユーザー

2020/02/26 06:03 編集

maisumakun さんや m.ts10806 さんのアドバイスがあって、こうしないといけないというところに至ったのだから、BAをつけるべきはそういった方々の回答に対してであるべきなんじゃないですかね。 ちなみに、BAは付け直しできますし、回答もコメントも再編集できますし、teratailの仕組み・使いこなしにも関心を持ってほしいです。 (ごめんねー、横からうるさい人だなーって思うかもしれないけど、こういうの見過ごせなくてね。)
freemac

2020/02/26 05:39 編集

BAの件は本当に申し訳ないです。最終的な解決方法を表記しないとまずいかな、、と 勝手な判断で自己解決にしてしまいました。次回からは気をつけたいと思います。
m.ts10806

2020/02/26 06:02

>BAは付け直しできますし、回答も再編集できますし m6uさんのコメントに上記があるのを、読まれてますか。
m.ts10806

2020/02/26 06:13 編集

>エラーが消えることだけを目的にすること→同じレベルに留まり続ける 私は「タイトルと解決方法が合致してない」という指摘をしています。エラー解決のみを目的とするなら「○○というエラーの解決方法」など、エラーに特化したタイトルであるべきです。 タイトルは「要件」です。 Q&AでQとAが合致していないということになります。 「認証システムを作りたい」→「出ていたエラーが消えました」 これは認証システム以前の問題を解決したに過ぎず、本来の目的の達成とはなりません。 エラー解決しただけでそれは「認証システム」と言えるのでしょうか? 認証という仕組みを舐めすぎです。設計どうなってますか? 「書籍にそってやってる」だけではないですか? ちなみに細かいことを言うと >少し違和感を感じます。 この表現のほうが違和感があります。頭痛が痛いと同じですね。
freemac

2020/02/26 08:11 編集

m6uさんの編集前のコメントを読んでの返信でした。現在teratailの使い方の部分を拝見させてもらいました。m.ts10806さんのおっしゃる通り、Q&Aの合致についての意見はごもっともだと思います。変更させていただきました。ただ、過去のコメントが、エラーが消えることだけを目的にすること→同じレベルに留まり続けると捉えてしまうような文面だったので、その点については言及させてもらいました。違和感を感じるは、おっしゃる通り違和感がありますね。わざわざ長文のご返答ありがとうございます。
m.ts10806

2020/02/26 08:14

>わざわざ長文のご返答ありがとうございます。 皮肉でしょうか。やめましょう、そういうの。厚意のみで成り立っている文字だけのやり取りの場所ではタブーかと。
freemac

2020/02/26 08:32 編集

いえ、皮肉ではなく、自分が長文の内容を投稿してしまったので、その返信をしてくださったことに対して感謝の意を述べたつもりです。語弊がありました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問