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

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

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

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

6110閲覧

【PHP】ログイン機能の実装

shar0430

総合スコア11

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

4クリップ

投稿2017/03/01 03:32

編集2017/03/01 08:09

PHP初心者です。
PHPの勉強がてら、会員制のページを作成してます。

新規会員登録機能は実装できていますが、
ログイン機能の実装がうまくいきません。
やりたいことを実現するにはどのように記述すればよいか
ご教授頂けませんでしょうか。

やりたいことは以下です。

<ToBe>
・DBに登録されているメールアドレス・パスワードでのみログイン可
・メールアドレス、パスワードのいずれかが空欄のときは
エラーメッセージを表示したい。
・ログイン後はメインページに遷移。

<AsIs>
・常にエラーメッセージが表示されている。
・登録済みのユーザでログインできない

以下、ソースです。

index.html (17/3/1 追記 ver1.1)

<?php require('dbconnect.php'); session_start(); if(isset($_POST)){ if(!empty($_POST)){ //ログインの処理 if($_POST['mail'] != '' && $_POST['pass'] != ''){ $sql = sprintf('SELECT * FROM users WHERE mail="%s" AND pass="%s"', mysqli_real_escape_string($db, $_POST['mail']), mysqli_real_escape_string($db, sha1($_POST['pass'])) ); $record = mysqli_query($db, $sql) or die(mysqli_error($db)); $result = mysqli_fetch_assoc($record); if(!empty($result)){ //ログイン成功 header('Location: main.php'); exit(); }else{ $error['login'] = 'failed'; } }else{ $error['login'] = 'blank'; } } } ini_set('display_errors', 1); error_reporting(E_ALL); ?> <!DOCTYPE html> <html> <head> <title>Login</title> </head> <body bgcolor="#FAFC7B"> <h2>Login</h2> <img src="nekos.jpg"> <form action="" method="post"> <dl> <dt>メールアドレス</dt> <dd><input type="text" name="mail" size="35" maxlength="255"> </dd> <dt>パスワード</dt> <dd><input type="password" name="pass" size="35" maxlength="255"></dd> </dl> <input type="submit" value="ログイン"> <?php var_dump($error['login']); ?> <?php if(!empty($error['login']) && $error['login'] == 'blank'): ?> <p><font color="red">* メールアドレスまたはパスワードをご記入ください</font></p> <?php endif; ?> <?php if(!empty($error['login']) && $error['login'] == 'failed'): ?> <p><font color="red">* ログインに失敗しました。正しくご記入ください。</font></p> <?php endif; ?> </form> <HR> <a href="join/register.php">新規登録</a>&nbsp; &nbsp; <a href="lookingforpass.php">パスワード照会</a>&nbsp; &nbsp; <a href="contact.html">お問い合わせ</a> </body> </html>

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

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

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

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

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

kei344

2017/03/01 05:04

質問文のコードはそれぞれコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
kei344

2017/03/04 05:46

まだ質問が「受付中」になっていますが、いったん「解決済」にされてはいかがでしょうか。また、解決されていないなら状況を追記ください。
shar0430

2017/03/05 02:44

皆さん、ご丁寧に御回答頂きありがとうございます。ベストアンサーは悩みましたが、解決のきっかけとなったKosuke_shibuyaに決めさせて頂きました。ありがとうございました。
guest

回答3

0

ベストアンサー

開発時は必ず、下に示したコードのように、

php

1ini_set('display_errors', 1); 2error_reporting(E_ALL);

を記述し、 エラーメッセージを表示してください
質問する際には、表示されたエラーを記述するようにしましょう。
もっとも、表示されたエラーには、「なぜうまくいかないか」の理由が書かれているものですから、質問を建てる前に、自己解決できる場合がほとんどです。

php

1<?php 2 3ini_set('display_errors', 1); 4error_reporting(E_ALL); 5 6require('dbconnect.php');

#やっつけサンプル

##SQL

sql

1CREATE TABLE `Users` ( 2 `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 3 `email` varchar(64) DEFAULT NULL, 4 `password` varchar(256) DEFAULT NULL, 5 PRIMARY KEY (`id`) 6) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 7 8-- password = 'password' 9INSERT INTO `Users` (`id`, `email`, `password`) 10VALUES 11 (1,'user@example.com','$2y$10$OqyHPnhhs7nFZGrB/P7wDuN1sZ7olqyc8r3bUTXIKRqg00eJRu/W2');

##index.php

php

1<?php 2/** 3 * index.php 4 */ 5ini_set('display_errors', true); 6error_reporting(E_ALL); 7 8session_start(); 9 10define('DSN', 'mysql:host=localhost;dbname=sample;charset=utf8'); 11define('USERNAME', 'root'); 12define('PASSWORD', 'password'); 13 14/** 15 * htmlspecialchars 16 */ 17function h($string) 18{ 19 return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); 20} 21 22/** 23 * SELECT 24 */ 25function select($sql, $params = []) 26{ 27 $options = [ 28 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 29 ]; 30 $objPdo = new PDO(DSN, USERNAME, PASSWORD, $options); 31 $stmt = $objPdo->prepare($sql); 32 $stmt->execute($params); 33 return $stmt->fetchAll(); 34} 35 36/** 37 * ログイン 38 */ 39function login() 40{ 41 if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') !== 'POST') { 42 return; 43 } 44 $email = filter_input(INPUT_POST, 'email'); 45 $password = filter_input(INPUT_POST, 'password'); 46 if (empty($email) || empty($password)) { 47 throw new Exception('メールアドレスおよびパスワードは入力必須です。'); 48 } 49 50 $sql = 'SELECT * FROM `Users` WHERE `email` = :email '; 51 $params = []; 52 $params['email'] = $email; 53 $rows = select($sql, $params); 54 55 $user = reset($rows); 56 if (count($rows) === 0 || !password_verify($password, $user['password'])) { 57 throw new Exception('メールアドレスおよびパスワードが間違っています。'); 58 } 59 60 session_regenerate_id(true); 61 $_SESSION['login_user'] = $user; 62 63 return true; 64} 65 66try { 67 if (login()) { 68 header('Location: top.php'); 69 } 70} catch (Exception $ex) { 71 $err = $ex->getMessage(); 72} 73?> 74<!DOCTYPE html> 75<html lang="en"> 76 <head> 77 <meta charset="utf-8"> 78 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 79 <meta name="viewport" content="width=device-width, initial-scale=1"> 80 81 <title>Signin Template for Bootstrap</title> 82 83 <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> 84 <style type="text/css"> 85 body { 86 padding-top: 40px; 87 padding-bottom: 40px; 88 background-color: #eee; 89 } 90 91 .form-signin { 92 max-width: 330px; 93 padding: 15px; 94 margin: 0 auto; 95 } 96 .form-signin .form-signin-heading, 97 .form-signin .checkbox { 98 margin-bottom: 10px; 99 } 100 .form-signin .checkbox { 101 font-weight: normal; 102 } 103 .form-signin .form-control { 104 position: relative; 105 height: auto; 106 -webkit-box-sizing: border-box; 107 -moz-box-sizing: border-box; 108 box-sizing: border-box; 109 padding: 10px; 110 font-size: 16px; 111 } 112 .form-signin .form-control:focus { 113 z-index: 2; 114 } 115 .form-signin input[type="email"] { 116 margin-bottom: -1px; 117 border-bottom-right-radius: 0; 118 border-bottom-left-radius: 0; 119 } 120 .form-signin input[type="password"] { 121 margin-bottom: 10px; 122 border-top-left-radius: 0; 123 border-top-right-radius: 0; 124 } 125 </style> 126 </head> 127 128 <body> 129 130 <div class="container"> 131 132 <?php if (isset($err)) : ?> 133 <div class="alert alert-danger"> 134 <p> 135 <?= h($err); ?> 136 </p> 137 </div> 138 <?php endif; ?> 139 140 <form class="form-signin" method="post"> 141 <h2 class="form-signin-heading">Please sign in</h2> 142 143 <label for="inputEmail" class="sr-only"> 144 Email address 145 </label> 146 <input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" autofocus> 147 148 <label for="inputPassword" class="sr-only"> 149 Password 150 </label> 151 <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password"> 152 153 <button class="btn btn-lg btn-primary btn-block" type="submit"> 154 Sign in 155 </button> 156 </form> 157 158 </div> <!-- /container --> 159 </body> 160</html>

##top.php

php

1<?php 2/** 3 * top.php 4 */ 5ini_set('display_errors', true); 6error_reporting(E_ALL); 7 8session_start(); 9 10/** 11 * htmlspecialchars 12 */ 13function h($string) 14{ 15 return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); 16} 17 18/** 19 * check_login 20 */ 21function check_login() 22{ 23 $res = (isset($_SESSION['login_user']) && $_SESSION['login_user'] != NULL); 24 if (!$res) { 25 header('Location: index.php'); 26 } 27} 28 29check_login(); 30?> 31<!DOCTYPE HTML> 32<html lang="ja"> 33 <head> 34 <meta charset="UTF-8"> 35 <title></title> 36 </head> 37 <body> 38 <?= h($_SESSION['login_user']['email']); ?> 39 </body> 40</html>

投稿2017/03/01 03:38

編集2017/03/01 14:19
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

質問とは全く関係ない部分ですが、

php

1pass=sha1($_POST['pass'])

暗号強度はほぼゼロなので使ってはいけません。
例:passが'5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8'ならパスワードは'password'と判る

× 固定値SALTを使う
http://qiita.com/shunsuke_takahashi/items/fcbe1e08aa94b208c14a

△ 個別SALTを使う
http://qiita.com/ms2sato/items/6005eea50def287090d0

○ password_hashを使う

php

1 2 // パスワード登録時 3 $sql = 'INSERT INTO users (mail, pass) VALUES (?, ?)'; 4 $stmt = mysqli_prepare($db, $sql); 5 mysqli_stmt_bind_param($stmt, 'ss', $_REQUEST['mail'], password_hash($_REQUEST['pass'], PASSWORD_DEFAULT)); 6 mysqli_stmt_execute($stmt); 7 8 // パスワード照合時 9 $sql = 'SELECT * FROM users WHERE mail = ?'; 10 $stmt = mysqli_prepare($db, $sql); 11 mysqli_stmt_bind_param($stmt, 's', $_REQUEST['mail']); 12 mysqli_stmt_execute($stmt); 13 mysqli_stmt_bind_result($stmt, $user); 14 mysqli_stmt_fetch($stmt); 15 if(password_verify($_REQUEST['pass'], $user['pass'])){ 16 // ログイン成功 17 }

あと手続き型mysqliはわかりにくいので、mysqliクラスにするかPDOをお勧めします。

投稿2017/03/01 12:44

rana_kualu

総合スコア92

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

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

0

まずはテンプレですが…質問文のコードはそれぞれコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
次にカッコが抜けていたりする箇所が多かったです。それが動作が想定と異なる原因になります。個人的にはIDEの利用をお勧めします。私がつかっているのはNetbeansですが、それ以外にも無料のIDEがあるので使ってみてください。少なくとも、文法エラーは一目瞭然でわかりますので…

で、実際に拝見したコードを軽く直してみました。とりあえず、ログインの為のDB読込はできると思いますよ。

php

1 2<?php 3require('dbconnect.php'); 4 5session_start(); 6 7if(isset($_POST)){ 8 if(!empty($_POST)){ //ログインの処理 9 if($_POST['mail'] != '' && $_POST['pass'] != ''){ 10 $sql = sprintf('SELECT * FROM users WHERE mail="%s" AND pass="%s"', 11 mysqli_real_escape_string($db, $_POST['mail']), 12 mysqli_real_escape_string($db, sha1($_POST['pass'])) 13 ); 14 $record = mysqli_query($db, $sql) or die(mysqli_error($db)); 15 $result = mysqli_fetch_assoc($record); 16 if(!empty($result)){ //ログイン成功 17 header('Location: main.php'); 18 exit(); 19 }else{ 20 $error['login'] = 'failed'; 21 } 22 }else{ 23 $error['login'] = 'blank'; 24 } 25 }else{ 26 echo '<p>NOSET!!!!</p>'; 27 } 28} 29 30?> 31 32<!DOCTYPE html> 33<html> 34 <head> 35 <title>ログインページ</title> 36 </head> 37 <body bgcolor="#FAFC7B"> 38 <h2>ログインページ</h2> 39 <img src="nekos.jpg"> 40 <form action="" method="post"> 41 <dl> 42 <dt>メールアドレス</dt> 43 <dd><input type="text" name="mail" size="35" maxlength="255"> </dd> 44 <dt>パスワード</dt> 45 <dd><input type="password" name="pass" size="35" maxlength="255"></dd> 46 </dl> 47 <input type="submit" value="ログイン"> 48 <?php if(!empty($error['login']) && $error['login'] == 'blank'): ?> 49 <p><font color="red">* メールアドレスまたはパスワードをご記入ください</font></p> 50 <?php endif; ?> 51 <?php if(!empty($error['login']) && $error['login'] == 'failed'): ?> 52 <p><font color="red">* ログインに失敗しました。正しくご記入ください。</font></p> 53 <?php endif; ?> 54 </form> 55<HR> 56<a href="join/register.php">新規登録</a> 57<a href="lookingforpass.php">パスワード照会</a> 58<a href="contact.html">お問い合わせ</a> 59</body> 60 61</html> 62

投稿2017/03/01 05:05

motuo

総合スコア3027

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

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

shar0430

2017/03/01 06:31

ご回答ありがとうございます。修正頂いたコードでも変化なしです。 常に $error['login'] = 'failed'; $error['login'] = 'blank'; なっている?ようで、 * メールアドレスまたはパスワードをご記入ください * ログインに失敗しました。正しくご記入ください。 が常に表示されています。 それとも <?php if分がうまく認識されていないんでしょうか、、
motuo

2017/03/01 06:40

そうですか…私の環境では正常に動いているので、何かしらの齟齬があるのでしょう。 まずは、$error['login']にどのような値が入っているか、確認頂けますか? * メールアドレスまたはパスワードをご記入ください * ログインに失敗しました。正しくご記入ください。 常に上記の2行が「同時に」出ている訳では無いですよね?もし、同時に出ているのであれば、コピペミスが考えられます。もう一度、私が提示したソースとご自分のソースを確認してください。 ログインボタンの下に、<?php var_dump($error['login']);?>を仕込むと、その時の値がブラウザで確認できるはずです。
shar0430

2017/03/01 07:59

<input type="submit" value="ログイン"> <?php var_dump($error['login']); ?> 上記の位置に仕込んでみましたが、ブラウザには何も出ません。 ちなみにレンタルウェブサーバを借りて本番環境で直接開発してます。
motuo

2017/03/01 08:04

では、改めてKosuke_Shibuyaさんの回答通り、 ini_set('display_errors', 1); error_reporting(E_ALL); を追加してみましょう。これで何かエラーが出てきませんか? また、上記対応後にも上手くいかないようでしたら、現時点のソースを質問に追記して頂けますか?
shar0430

2017/03/01 08:16

デバッグがブラウザに表示されない件についてですが php.iniも問題ないようです。 display_startup_errors=Off  display_errors=On  error_reporting=E_ALL & ~E_NOTICE 
motuo

2017/03/01 08:22 編集

質問文のソース、//require('dbconnect.php'); を外して $db = mysqli_connect("127.0.0.1", "test", "test", "test"); としても正常に動きますね。。。 もしかしたら、dbconnect.phpで例外が発生しているのかもしれませんね。 初期画面表示の画像と、ログインボタン押下後のハードコピーを見ると何か浮かぶかもしれませんが… 環境となると、もはやお手上げかもしれません。
shar0430

2017/03/01 08:31

$db = mysqli_connect("127.0.0.1", "test", "test", "test"); に変えても表示結果変わりませんね。 謎です。 ありがとうございました。。。。
motuo

2017/03/01 08:34

一応、、、言葉足らずだったかもしれませんが、 mysqli_connect("ホスト名", "ユーザ", "パスワード", "DB名"); ですよ。大丈夫ですよね?ご自身の環境の文字に変えてあげてくださいね。 それでもダメなら、いよいよちょっと分からないです。。。
退会済みユーザー

退会済みユーザー

2017/03/01 09:02

PHPの実行環境で動作させていないように思えます。つまり、アドレスバーが「file:///」の状態。
退会済みユーザー

退会済みユーザー

2017/03/01 19:30 編集

ini_set('display_errors', 1); error_reporting(E_ALL); はファイルの先頭に入れないと意味がありません。 あと、ファイル名は index.html ではなく、 index.php でなければなりません。
shar0430

2017/03/02 02:32

ファイル名をindex.phpに変更したところ、エラーメッセージ出力等、PHPが正常に動作しました。 ありがとうございます。初歩的なミスで恐縮です。エラーメッセージを元に修正かけたいと思います。 どうにもエラーが解消しない場合に、再度質問させて頂ければと思います。
motuo

2017/03/02 03:06

>Kosuke_Shibuyaさん そもそもの問題でしたね…気付ければ良かった…フォローして頂き、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問