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

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

ただいまの
回答率

90.12%

ログインフォームがウンともスンとも言いません。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,579

YukaSaku

score 41

汚いソースですみません。
ネットで調べながらmysqliを使って、ログインフォームを作っています。
ログインフォームの入力項目はusernameとpasswordのみです。

(registerの入力項目はusername, phone, email, password, gender(ラジオボタン)で、DBにはこの5項目以外にIDとDateが追加されます。)

PHPエラーは無いようなのですが、DBにあるユーザー名を入れても反応が無いので色んな箇所にechoを入れてみたのですがそれでも反応がありません。
sqlにつながらなかったらエラーが出るようにもしてるのですが、それも出ません。

何が悪いのでしょうか?

<?php
session_start();
ini_set("display_errors","on");
error_reporting(E_ALL | E_STRICT);
ini_set("include_path","./includes");
include("dbinfo.inc");

//  initialize error msg
$errorMessage = "";
$cust_id = "";
$status = "none";
//  when pressed login button
if (isset($_POST['login'])) {
    $mysqli = new mysqli($host,$user,$passwd,$dbname);
    // $cxn = mysqli_connect($host,$user,$passwd,$dbname);
    if ($mysqli->connect_error) {
    echo $mysqli->connect_error;
    exit();
} else {
    //$mysqli->set_charset("utf8");
    if(isset($_SESSION["username"])){
  $status = "loggedin";
  echo $status;
  echo $_SESSION["username"];
    //$username = $mysqli->real_escape_string($_POST['username']);
        //password = $mysqli->real_escape_string($_POST['password']);
    // check user ID
    if (empty($_POST['username'])) {
        $errorMessage = 'It is empty the User name';
    } else if (empty($_POST['password'])) {
        $errorMessage = 'It is empty the Password';
    }
    if (!empty($_POST['username']) && !empty($_POST['password'])) {
        $sql = "SELECT user_id, username FROM login WHERE user_id=? AND username=?";
        if ($stmt = $mysqli->prepare($sql)) {
    // 条件値をSQLにバインドする(補足参照)
    $user_id = $row["user_id"];
    $username = $row["username"];
    $stmt->bind_param("is", $user_id, $username);

$stmt->execute();

$stmt->bind_result($user_id, $username);
    while ($stmt->fetch()) {
        echo "ID=$user_id, NAME=$username<br>"; 
    }
    $stmt->close();

    $stmt->store_result(); // これ忘れるとnum_rowsは0
echo "rows=" . $stmt->num_rows;
}


 //結果の行数が1だったら成功
  if($stmt->num_rows == 1){
    $stmt->bind_result($password);
    while ($stmt->fetch()) {
      if(password_verify($_POST["password"], $password)){
        $status = "ok";
        echo $status;
        header("Location: loggedin.php");
        //セッションにユーザ名を保存
        $_SESSION["username"] = $_POST["username"];
        break;
      }else{
        $status = "failed";
        echo $status;
        $errorMessage = 'Wrong User ID or Password.';
        break;
      }
    }
  }else
    $status = "failed";
    $errorMessage = 'Wrong User ID or Password.';
}
}$mysqli->close();
    }
}
?>

<!doctype html>
    <head>
            <meta charset="UTF-8">
            <title>Login</title>
    </head>
    <body>
        <h1>Login</h1>
        <form id="loginForm" name="loginForm" action="" method="POST">
 <fieldset  style="border:1px dashed #66FFCC;">
                <legend>LoginForm</legend>
                <div><?php echo htmlspecialchars($errorMessage, ENT_QUOTES); ?></div>
                <label for="username">User ID</label>
                <input type="text" id="username" name="username" value="<?php if (!empty($_POST["username"])) {
                echo htmlspecialchars($_POST["username"], ENT_QUOTES);} ?>">
                <br>
                <label for="password">Password</label><input type="password" id="password" name="password" value="">
                <br>
                <input type="submit" id="login" name="login" value="login">
            </fieldset>
        </form>
        <br>
        <form action="register.php">
                <fieldset  style="border:1px dashed #66FFCC;">
                    <legend>Registration</legend>

                <input type="submit" value="Register">
            </fieldset>
        </form>
    </body>
</html>

こちらがデータベースの構造になります。
cust_ID     int(5)
username    varchar(15)
phone       varchar(15)
email       varchar(50)
password    varchar(60)    
gen         varchar(6)
date        datetime    

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • s8_chu

    2017/05/13 00:54

    データベースの構造を追記していただけませんか?

    キャンセル

  • YukaSaku

    2017/05/13 01:09

    ありがとうございます。データベース構造を追加しました。最初のDBの説明も説明不足だったので少し変更しました。

    キャンセル

回答 2

checkベストアンサー

+3

データベースを以下のようにして、

CREATE TABLE `login`(
    `cust_ID` int(5) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `username` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
    `phone` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
    `email` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
    `password` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
    `gender` varchar(6) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
    `date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci


以下のデータを入れました

INSERT INTO `login` (`cust_ID`, `username`, `phone`, `email`, `password`, `gender`, `date`) VALUES (NULL, 'user1', '0123456789', 'example@example.com', '$2y$10$3N3CA20gllPFdF7iTAaEXe8hUXEskBN0cMUkwAdf4A36UJeBPvcgq', 'man', CURRENT_TIMESTAMP)


そのとき、質問者さんが実現したいことは以下のように行えると思いますが、いかがでしょうか?

<?php
session_start();
ini_set("display_errors", "on");
error_reporting(E_ALL | E_STRICT);

$errorMessage = "";
$cust_id = "";
$status = "none";
$rows = 0; // 追加。
$username_result = ""; // 追加。

if (isset($_POST['login'])) {

    $mysqli = new mysqli("host", "username", "password", "sample01");

    if ($mysqli->connect_error) {
        echo $mysqli->connect_error;
        exit();
    } else {
        $mysqli->set_charset("utf8"); // 追加。

        /* 何がしたいかわからなかったのでコメントアウト。
        if (isset($_SESSION["username"])) {
            $status = "loggedin";

            if (empty($_POST['username'])) {
                $errorMessage = 'It is empty the User name';
            } else {
                if (empty($_POST['password'])) {
                    $errorMessage = 'It is empty the Password';
                }
            }
        }
        */

        if (
            !empty($_POST['username']) &&
            !empty($_POST['password'])
        ) { // 入力されたユーザーネームがあるかどうかを確認したいのではないかと推測して変更、追記をした。
            $sql = "SELECT `username` FROM `login` WHERE `username`=?";
            if ($stmt = $mysqli->prepare($sql)) {
                $stmt->bind_param("s", $_POST['username']);
                $stmt->execute();

                $stmt->bind_result($username);
                while ($stmt->fetch()) {
                    $username_result = $username;
                }

                $stmt->store_result(); // これ忘れるとnum_rowsは0
                $rows = $stmt->num_rows;
                $stmt->close();
            }


            if ($rows === 1) {
                $sql = "SELECT `password` FROM `login` WHERE `username`=?";
                if ($stmt = $mysqli->prepare($sql)) {
                    $stmt->bind_param("s", $username_result);
                    $stmt->execute();

                    $stmt->bind_result($password_result);
                    while ($stmt->fetch()) {
                        if (password_verify($_POST["password"], $password_result)) {
                            $status = "ok";
                            echo $status;
                            $_SESSION["username"] = $_POST["username"];
                            header("Location: loggedin.php");
                        } else {
                            $status = "failed";
                            $errorMessage = 'Wrong User ID or Password.';
                        }
                    }

                    $stmt->close();
                }
            } else {
                $status = "failed";
                $errorMessage = 'Wrong User ID or Password.';
            }
            // $errorMessage = 'Wrong User ID or Password.'; 不要。
        } else {
            $errorMessage = "IDもしくはパスワードが未入力。"; // 追加。
        }
    }
    $mysqli->close();
}
?>
<!doctype html>
<html><!-- htmlタグの開始タグがなかった。 -->
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<h1>Login</h1>
<form id="loginForm" name="loginForm" action="" method="POST">
    <fieldset style="border:1px dashed #66FFCC;">
        <legend>LoginForm</legend>
        <div>
            <?php echo htmlspecialchars($errorMessage, ENT_QUOTES); ?>
        </div>
        <label for="username">User ID</label>
        <input type="text" id="username" name="username" value="<?php if (!empty($_POST["username"])) {
            echo htmlspecialchars($_POST["username"], ENT_QUOTES);
        } ?>">
        <br>
        <label for="password">Password</label><input type="password" id="password" name="password" value="">
        <br>
        <input type="submit" id="login" name="login" value="login">
    </fieldset>
</form>
<br>
<form action="register.php">
    <fieldset style="border:1px dashed #66FFCC;">
        <legend>Registration</legend>

        <input type="submit" value="Register">
    </fieldset>
</form>
</body>
</html>

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/13 04:16

    よくわからないので、このように書き換えて見ました。
    $mysqli = new mysqli('$host', '$user', '$passwd', '$dbname');

    すると、以下のような新しいエラーが出てきました。
    Warning: mysqli::__construct(): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution in ****
    Warning: mysqli::__construct(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution in******
    php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution

    キャンセル

  • 2017/05/13 04:19

    以前同じ内容のプログラムをPDOで書いた時にはこのようなコードで接続してます。
    $dsn = "mysql:dbname=".$dbname.";host=".$host;
    try {
    $pdo = new PDO($dsn, $user, $passwd, array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
    で、現在もきちんと動きます。

    キャンセル

  • 2017/05/13 12:51

    $mysqli = new mysqli("host", "user", "passwd", "dbname");のダブルコーテーションを取って、$host, $user...と書き直し、シングルコーテーションが、なぜか母音に付けるアクセントの点だったので、それをシングルコーテーションに書き直したところ、他のエラーが沢山出てきましたが、とりあえずプログラム上で何が起きてるのかが見えるようになったのでこの度は解決としようと思います。
    ありがとうございました!

    キャンセル

+3

ログインフォームって、いろいろな基礎要素が詰まっていて面白いのですが、結構難しいです。
直接の回答ではないのですが、初学者向けの注意点を網羅的に説明してくれている記事があるので紹介します。

PHPでログイン機能を実装するチュートリアル #1

ちょっと難しい箇所もありますが、ログインフォームってサイトの要になるんで、そこそこスキルと知識が必要です。
記事に記述されている内容を理解して、コードを見直してみてはいかがでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/05/13 12:53

    ほんと難しいですよね。
    リンク、ありがとうございます。じっくり見てみようと思います。

    キャンセル

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

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