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

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

ただいまの
回答率

89.06%

PHPでデータのINSERTができない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 955

nopakat

score 6

PHP初学者です。

Macを使用し、エディタはAtom、ローカル開発環境はMAMPを使用しています。

現在、たにぐちまことさん著「よくわかるPHPの教科書 PHP7対応版」で学習を進めております。

Chapter6-5で「Twitter風ひとこと掲示板を作る」の中で、ユーザー登録の際に、上手くユーザーのデータがデータベースにINSERTできません。

check.phpでの内容確認後、本来はthanks.phpで登録完了となるはずが、check.phpのページで真っ白になります。

以下、記述コードです。

データベース名:mini_bbs
テーブル名:members

テーブル構造: 定義 AI
id INT(11)
name VARCHER(255)
email VARCHER(255)
password VARCHER(100)
picture VARCHER(255)
created DATETIME
modified TIMESTAMP

【dbconnect.php】

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="css/style.css">

<title>よくわかるPHPの教科書</title>
</head>
<body>
  <header>
    <h1 class="font-weight-normal">よくわかるPHPの教科書</h1>
  </header>

  <main>
<?php
try {
  $db = new PDO('mysql:dbname=mini_bbs;host=localhost;charset=utf8', 'root', 'root');
} catch (PDOException $e) {
  echo 'DB接続エラー: ' . $e->getMessage();
}
 ?>
</main>
</body>
</html>

【index.php】

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="css/style.css">

<title>よくわかるPHPの教科書</title>
</head>
<body>
  <main>
    <?php

    require('../dbconnect.php');

    session_start();

    if(!empty($_POST)) {
      //エラー項目の確認
      if($_POST['name'] == '') {
        $error['name'] = 'blank';
      }
      if($_POST['email'] == '') {
        $error['email'] = 'blank';
      }
      if(strlen($_POST['password']) < 4) {
        $error['password'] = 'length';
      }
      if($_POST['password'] == '') {
        $error['password'] = 'blank';
      }
      $fileName = $_FILES['image'] ['name'];
      if(!empty($fileName)) {
        $ext = substr($fileName, -3);
        if($ext != 'jpg' && $ext != 'gif') {
          $error['image'] = 'type';
        }
      }

      //重複アカウントのチェック
      if(empty($error)) {
        $member = $db->prepare('SELECT COUNT(*) AS cnt FROM members WHERE email=?');
        $member->execute(array($_POST['email']));
        $record = $member->fetch();
        if($record['cnt'] > 0) {
          $error['email'] = 'duplicate';
        }
      }

      if(empty($error)) {
        //画像をアップロードする
        $image = date('YmdHis') . $_FILES['image']['name'];
        move_uploaded_file($_FILES['image']['tmp_name'], '../member_picture/' . $image);

        $_SESSION['join'] = $_POST;
        $_SESSION['join']['image'] = $image;
        header('Location: check.php');
        exit();
      }
    }

    //書き直し
    if($_REQUEST['action'] == 'rewrite') {
      $_POST = $_SESSION['join'];
      $error['rewrite'] = true;
    }
     ?>
      <p>次のフォームに必要事項をご記入ください。</p>
      <form action="" method="post" enctype="multipart/form-data">
        <dl>
          <dt>ニックネーム<span class="required">必須</span></dt>
          <dd><input type="text" name="name" size="35" maxlength="255" value="<?php echo htmlspecialchars($_POST['name'], ENT_QUOTES); ?>" />
          <?php if($error['name'] == 'blank'): ?>
            <p class="error">* ニックネームを入力してください</p>
          <?php endif; ?>
          </dd>
          <dt>メールアドレス<span class="required">必須</span></dt>
          <dd><input type="text" name="email" size="35" maxlength="255" value="<?php echo htmlspecialchars($_POST['email'], ENT_QUOTES); ?>" />
            <?php if($error['email'] == 'blank'): ?>
              <p class="error">* メールアドレスを入力してください</p>
            <?php endif; ?>
            <?php if($error['email'] == 'duplicate'): ?>
            <p class="error">* 指定されたメールアドレスはすでに登録されています</p>
          <?php endif; ?>
          </dd>
          <dt>パスワード<span class="required">必須</span></dt>
          <dd><input type="password" name="password" size="10" maxlength="20" value="<?php echo htmlspecialchars($_POST['password'], ENT_QUOTES); ?>" />
            <?php if($error['password'] == 'blank'): ?>
              <p class="error">* パスワードを入力してください</p>
            <?php endif; ?>
            <?php if($error['password'] == 'length'): ?>
              <p class="error">* パスワードは4文字以上で入力してください</p>
            <?php endif; ?>
          </dd>
          <dt>写真など</dt>
          <dd><input type="file" name="image" size="35" />
            <?php if($error['image'] == 'type'): ?>
              <p class="error">* 写真などは「.gif」または「.jpg」の画像を指定してください</p>
            <?php endif; ?>
            <?php if(!empty($error)): ?>
              <p class="error">* 恐れ入りますが、画像を改めて指定してください</p>
            <?php endif; ?>

          </dd>
        </dl>
        <div><input type="submit" value="入力内容を確認する" /></div>
      </form>
   </main>
</body>
</html>

【check.php】

<?php
session_start();
require('../dbconnect.php');

if(!isset($_SESSION['join'])) {
  header('Location: index.php');
  exit();
}

if(!empty($_POST)) {
  //登録処理をする
  $statement = $db->prepare('INSERT INTO members SET name=?, email=?, password=?, picture=?, created=NOW()');
  $ret = $statement->execute(array(
    $_SESSION['join']['name'],
    $_SESSION['join']['email'],
    shal($_SESSION['join']['password']),
    $_SESSION['join']['image']
  ));
  unset($_SESSION['join']);

  header('Location: thanks.php');
  exit();
}
 ?>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="css/style.css">

<title>よくわかるPHPの教科書</title>
</head>
<body>
  <main>


      <form action="" method="post">
        <input type="hidden" name="action" value="submit" />
        <dl>
          <dt>ニックネーム</dt>
          <dd>
            <?php echo htmlspecialchars($_SESSION['join']['name'], ENT_QUOTES); ?>
          </dd>
          <dt>メールアドレス</dt>
          <dd>
            <?php echo htmlspecialchars($_SESSION['join']['email'], ENT_QUOTES); ?>
          </dd>
          <dt>パスワード</dt>
          <dd>
          【表示されません】
        </dd>
          <dt>写真など</dt>
          <dd>
            <img src="../member_picture/<?php echo htmlspecialchars($_SESSION['join']['image'], ENT_QUOTES); ?>" width="100" height="100" alt="" />
          </dd>
        </dl>
        <div><a href="index.php?action=rewrite">&laquo;&nbsp;書き直す</a> | <input type="submit" value="登録する" /></div>
      </form>
   </main>
</body>
</html>

【thanks.php】

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="css/style.css">

<title>よくわかるPHPの教科書</title>
</head>
<body>
  <main>
    <p>ユーザー登録が完了しました</p>
    <p><a href="../"> ログインする</a></p>

   </main>
</body>
</html>

全てのコードの記述も確認しましたが、データベースへの接続もできており、ミスしている箇所が見つけられません。

先人のお力をお借りしたく、質問させていただきます。

何卒宜しくお願い申し上げます。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Orlofsky

    2019/09/04 23:18

    テーブルの定義情報は、できれば CREATE TABLE に修正できると適切なコメントが付きやすいです。

    キャンセル

  • Orlofsky

    2019/09/04 23:19

    コードは https://teratail.com/help/question-tips#questionTips3-7 の [コード] に修正してください。

    キャンセル

  • nopakat

    2019/09/04 23:27

    Orlofsky様
    上記の件、ご指摘頂きまして、誠にありがとうございます。
    訂正させて頂きます。

    キャンセル

回答 1

checkベストアンサー

+2

require('../dbconnect.php');ではエラーが出ていない前提での回答です。

check.php の以下部分をファイルの先頭に移動し、★部分のechoを削除してください。
レスポンスヘッダーの出力(header('Location: check.php');)は、レスポンスボディを一文字でも出力すると機能しません。

(php.net) header

覚えておいて頂きたいのは、header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです。

<?php
    session_start();
    require('../dbconnect.php');

    if(!isset($_SESSION['join'])) {
      header('Location: index.php');
      exit();
    }

    if(!empty($_POST)) {
      //登録処理をする
      $statement = $db->prepare('INSERT INTO members SET name=?, email=?, password=?, picture=?, created=NOW()');
      //★echo $ret = $statement->execute(array(
      $ret = $statement->execute(array(
        $_SESSION['join']['name'],
        $_SESSION['join']['email'],
        shal($_SESSION['join']['password']),
        $_SESSION['join']['image']
      ));
      unset($_SESSION['join']);

      header('Location: thanks.php');
      exit();
    }
     ?>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/09/05 00:11

    Y.H.様
    ありがとうございます。
    ご指摘の箇所もファイル先頭へ移動いたしましたが、結果は変わりませんでした、、、。
    その前のindex.phpでは正常にheader('Location: check.php');が機能し、check.phpへ移動できており、他に何か要因として考えられることはありますでしょうか。
    ご助力いただき、本当にありがとうございます。

    キャンセル

  • 2019/09/05 00:15

    phpまたはapacheのエラーログに何か出力されてませんか?

    キャンセル

  • 2019/09/05 00:35

    Y.H.様
    すみません、今エラーログ拾いに行き、下記の内容で確認しましたら解決致しました。

    [04-Sep-2019 15:30:29 UTC] PHP Fatal error: Uncaught Error: Call to undefined function shal() in /Applications/MAMP/htdocs/post/join/check.php:16
    Stack trace:

    × shal

    ○ sha1

    と修正しましたら解決致しました。

    ご助言いただけましたおかげで解決致しました。
    ありがとうございます。

    キャンセル

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

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

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