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

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

ただいまの
回答率

87.59%

ユーザー登録機能の実装

受付中

回答 3

投稿

  • 評価
  • クリップ 2
  • VIEW 1,472

score 23

ユーザー登録の際、idとpasswordを入力してもらい、それをkeijibanテーブルに保存して、保存したものをSELECTで表示させる機能の実装を行っておりますが、結果は表示されず困っております。
度々申し訳ございませんが、対処法をご教授いただければ幸いです。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>簡易掲示板</title>
</head>


<body>

    <h1>ユーザー登録</h1>
    <form method="post" action="DB.php">
        Id:<input type="text" name="ID" value=""><br>
        Password:<input type="text" name="NAME" value="">
        <input type="submit" name="regist" value="Post">
    </form>

    <?php
  $host = '*******';
  $dbname = '***********';
  $dbuser = '*************';
  $dbpassword = '*************';
  $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8","$dbuser","$dbpassword");

    #データベースへの登録
    if( isset($_POST['regist']) ){
        $id = $_POST['ID'];
        $name = $_POST['NAME'];
        $sql = "INSERT INTO keijiban (id, name) VALUES ('$id', '$name')";
        $res = $pdo->query($sql);

         #テーブル内容の表示
    $sql = "SELECT * FROM keijiban ORDER BY id DESC";
    $stmt = $pdo->query($sql);
    foreach ($stmt as $row) {
        echo $row['ID'].' '.$row['NAME'];
        echo '<br>';
    }
}

    #リロード時の二重投稿を防止
    if($_SERVER['REQUEST_METHOD'] === 'POST') {
    header('Location:DB.php', true, 303);
    }
    #終了
    $stmt = null;
    $pdo = null;
?>
</body>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2019/02/14 14:08

    「解決」は「質問の解決」となってしまうと「理解した」という意味にはなりません。
    私のように「今後直面しうる問題も含めた上でのアドバイス」を蛇足的に書く回答者も少なくないです。
    となると「質問・問題の解決」だけではなく「回答内容をきちんと理解できたか」を「解決基準」としないと
    せっかく(ある程度の労力や時間をかけて)書かれたコメントが全て無駄になります。
    回答者であるという立場から、今後おきうるであろう問題も経験してきているわけですから、
    そこをきちんと避けられるようなアドバイスが書かれているのであれば、理解しようと努めてください。
    本来は 理解した=解決した なので。
    https://teratail.com/help/question-tips#questionTips4-2
    >多くの回答ユーザーが、~~
    のところを参照。

    キャンセル

  • 退会済みユーザー

    2019/02/14 14:13

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

  • cerfweb

    2019/02/18 22:20

    ご質問自体には関係ありませんが、パスワードは<input type="text" ...>ではなく<input type="password" ...>とした方がいいでしょう。また、データベースにパスワードを保存する場合は、必ずpassword_hash()などでハッシュ処理をしてからにしましょう。そうでないと、データベースが攻撃を受けたときにパスワードが盗まれてしまうなど、セキュリティ上大変危険です。

    キャンセル

回答 3

+2

header('Location:DB.php', true, 303);
と移動しているので結果は表示されません
また

foreach ($stmt as $row) {
        echo $row['ID'].' '.$row['NAME'];
        echo '<br>';
    }


とID NAMEとしているようですが実際のテーブル構造は
id, name
なので表示されません

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/14 14:20

    あとheader()あるのにその前でechoで画面出力してるところもNGですね。

    キャンセル

  • 2019/02/14 23:15

    修正してみたところ、正常に動作しました。ありがとうございます。

    キャンセル

0

テーブルの状態にもよりそうですね

create table keijiban(id int unique,name varchar(100));


として

<h1>ユーザー登録</h1>
<form method="post">
Id:<input type="text" name="ID" value=""><br>
Password:<input type="text" name="NAME" value="">
<input type="submit" name="regist" value="Post">
</form>

<?php
$regist=filter_input(INPUT_POST,'regist');
$id=filter_input(INPUT_POST,'ID');
$name=filter_input(INPUT_POST,'NAME');
if(!is_null($regist) and $id!=="" and $name!==""){
  try{
    $pdo = new PDO($dsn, $user,$password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $sql = "INSERT IGNORE INTO keijiban (id, name) VALUES (?,?)";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$id,$name]);
    $sql = "SELECT * FROM keijiban ORDER BY id DESC";
    $stmt = $pdo->query($sql);
    $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
    print_r($rows);
  }catch(PDOException $e){
    die($e->getMessage());
  }
}


IDとNAMEという名前でuserとpasswordを管理するのは微妙です
ちなみにpasswordはきちんとハッシュして管理しないとあとで
大変なことになりますので注意してください
(テスト段階では仕方ないので平文パスワードとします)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

直接的な原因は既に回答にあるとおり。
「POSTのときにしかSELECT実行していない」から。
そのPOSTのときにリダイレクト入れてるのでSELECTは永遠に実行されません。
インデントきちんとそろえると分かりやすいですね。(前の質問の回答にヒントとなるキーワードはたくさんあったはずですが)

Eclipseのコードフォーマット機能使った結果

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>簡易掲示板</title>
</head>


<body>

    <h1>ユーザー登録</h1>
    <form method="post" action="DB.php">
        Id:<input type="text" name="ID" value=""><br> Password:<input
            type="text" name="NAME" value=""> <input type="submit" name="regist"
            value="Post">
    </form>

    <?php
    $host = '*******';
    $dbname = '***********';
    $dbuser = '*************';
    $dbpassword = '*************';
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", "$dbuser", "$dbpassword");

    // データベースへの登録
    if (isset($_POST['regist'])) {
        $id = $_POST['ID'];
        $name = $_POST['NAME'];
        $sql = "INSERT INTO keijiban (id, name) VALUES ('$id', '$name')";
        $res = $pdo->query($sql);

        // テーブル内容の表示
        // mts10806 ここでSELECT実行してるということはいつ実行される?
        $sql = "SELECT * FROM keijiban ORDER BY id DESC"; 
        $stmt = $pdo->query($sql);
        foreach ($stmt as $row) {
            echo $row['ID'] . ' ' . $row['NAME'];
            echo '<br>';
        }
    }

    // リロード時の二重投稿を防止
    // mts10806 POSTだったらリダイレクト。SELECT結果は意味ない。というかheader()の前に出力があることになるのでNG
    // http://php.net/manual/ja/function.header.php
    // > 覚えておいて頂きたいのは、header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです。 頻出するエラーとして、include または require 関数、他のファイルをアクセスする関数に 空白または空行があり、header() の前に出力が 行われてしまうというものがあります。同じ問題は、単一の PHP/HTML ファイルを使用している場合でも存在します。
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        header('Location:DB.php', true, 303);
    }
    // 終了
    $stmt = null;
    $pdo = null;
    ?>
</body>
</html>

項目を増やしたテーブルを新規に作り

項目の設定を加味して整合性をとれば良いです。
Not Nullにしてるならそこは「必須である」なのでinsertに含まれてなかったらエラーになります。
エラーを捕捉するよな仕組みになってないのでそこに気づけません。
前の前の質問の回答参照


登録処理と表示処理を一緒の画面にしたい場合、登録処理と取得処理を同じ中でやっているのはNG
あと、「POST送信する」ということは送信された内容を以て最初からプログラムを読み出すことになるので、
順序的にはPHPを先に書くべき。

<?php
$host = '*******';
$dbname = '***********';
$dbuser = '*************';
$dbpassword = '*************';
$pdo = null;
try{
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", "$dbuser", "$dbpassword");
}catch(PDOException $e){
    var_dump($e);
    die();
}

// データベースへの登録
//if (isset($_POST['regist'])) { //mts10806 だから、これは良くないコーディングですって
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $id = $_POST['ID'];
    $name = $_POST['NAME'];
    $sql = "INSERT INTO keijiban (id, name) VALUES ('$id', '$name')";
    //$res = $pdo->query($sql);
    //mts10806$res使ってない。それなら下記で。いずれにしても「絶対成功する前提」のコーディングはNG
    if($pdo->query($sql)){
        header('Location:DB.php', true, 303);
    }else{
        die("登録失敗");//mts10806 一応入れておく
    }
    /*mts10806
     本来はこのようにすべき
$stmt = null;
try{
    $id=filter_input(INPUT_POST,'ID');
    $name=filter_input(INPUT_POST,'NAME'); //SQLに入れる前にバリデーションは必須。今回は省略
    $sql = "INSERT INTO keijiban (id, name) VALUES (:id,:name)";
    $stmt = $pdo->prepare($sql);
    $stmt->bindValue(":id",$id);
    $stmt->bindValue(":name",$name);
    $stmt->execute([$id,$name]);
}catch(PDOException $e){
    var_dump($e);
    $pdo = null;
    die();
} finally {
    $stmt = null;
}
     *
     */
}
// テーブル内容の表示
$sql = "SELECT * FROM keijiban ORDER BY id DESC";
$stmt = $pdo->query($sql);
$list = "";
foreach ($stmt as $row) {
    $list .= $row['id'] . ' ' . $row['name']; //mts10806 添え字は大文字小文字を大別する。揃えること
    $list .= '<br>';
}
//mts10806 ここでもtry-catchあると丁寧
// 終了
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>簡易掲示板</title>
</head>


<body>

    <h1>ユーザー登録</h1>
    <form method="post" action="DB.php">
        Id:<input type="text" name="ID" value=""><br> Password:<input
            type="text" name="NAME" value=""> <input type="submit" name="regist"
            value="Post">
    </form>
    <?php echo $list;?>
</body>
</html>

あとは前の質問の回答で書いたIDEの導入は必須。インデントも「フォーマット」機能があったりで一発でいい感じに揃う。
ある程度今回含めて書きましたが、その前の前の質問の回答で書いた簡易コードレビューの指摘コメントは熟読のこと。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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