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

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

ただいまの
回答率

88.21%

お問い合わせフォームから送信したデータがデータベースに格納されない

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 5,774

k2font

score 13

ドットインストールを見ながらPHPでお問い合せフォームを作っています。
8割方完成したのですが、どうしてもドハマりしてしまう部分があるので、質問させていただきます。

お問い合わせのフォームには「名前」「メールアドレス」「お問い合わせの内容」を書く欄があり、すべての欄に記入をして送信ボタンを押すと、一見送信が成功したように見えるのですが、データベースの中身を見ると「メールアドレス」と「お問い合わせの内容」だけ何も格納されないままになります(「名前」だけ格納される)。

これは何故でしょうか。phpMyAdminでデータベースの設定をよく確認したり、PHPのコードを確認しましたが、解決する気配がありません。
以下にソースコードと開発環境を示しますので、ご回答よろしくお願いします。

以下、コード
contact.php(メインページ)
    require_once('config.php');
    require_once('functions.php');

    session_start();

    if($_SERVER['REQUEST_METHOD'] != "POST") {
        //投稿前
        //CSFR対策
        setToken();
    } else {
        //投稿後
        checkToken();
        
        $name = $_POST['name'];
        $email = $_POST['email'];
        $memo = $_POST['memo'];
        
        $error = array();
        
        //エラー処理
        if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $error['email'] = 'メールアドレスの形式が正しくありません';
        }
        
        if($email = '') {
            $error['email'] = 'メールアドレスを入力してください';
        }
        
        if($memo = '') {
            $error['memo'] = 'お問い合せ内容を入力してください';
        }
        
        if(empty($error)) {
            // DBに格納
            $dbh = connectDb();
            
            $sql = "insert into entries
                    (name, email, memo, created, modified)
                    values
                    (:name, :email, :memo, now(), now())";
            
            $stmt = $dbh -> prepare($sql);
            $params = array(
                ":name" => $name,
                ":email" => $email,
                ":memo" => $memo
            );
            
            $stmt -> execute($params);
            
            //送信完了ページヘ
            header('Location: '.SITE_URL.'thanks.php');
            exit;
        }
    }
?>

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0">
        <title>お問い合わせ</title>
        
        <link rel="stylesheet" href="css/metro-bootstrap.css">
        <link href="css/metro-bootstrap-responsive.css" rel="stylesheet">
        <link rel="stylesheet" href="css/main.css">
        <link href="css/iconFont.css" rel="stylesheet">
        <script src="js/jquery/jquery.min.js"></script>
        <script src="js/jquery/jquery.widget.min.js"></script>
        <script src="js/jquery/jquery.mousewheel.js"></script>
        <script src="min/metro.min.js"></script>
        <script src="js/aScroller.js"></script>
        <script src="bootstrap/js/bootstrap.min.js"></script>

        <link rel="shortcut icon" href="img/favicon.ico">
    </head>
    
    <body class="metro">
        <div id="s_menu">
            <div class="maintext">
                <h1>お問い合わせ</h1>
                <p>お問い合せは以下のフォームよりお願いします</p>
                <p>※「*」部分は必須項目です</p>
                
                <!-- 以下フォーム部分 -->
                <form method="post" action="">
                    <p>お名前* : <input type="text" name="name" value=""></p>
                    <p>
                        メールアドレス* : <input type="text" name="email" value="<?php echo h($email); ?>">
                        <?php
                            if($error['email']) {
                                echo h($error['email']);
                            }
                        ?>
                    </p>
                    <p>お問い合わせ内容* : </p>
                    <p><textarea name="memo" cols="100" rows="15"><?php echo h($email); ?></textarea></p>
                    <?php
                        if($error['memo']) {
                            echo h($error['memo']);
                        }
                    ?>
                    <p><input type="submit" value="送信"></p>
                    <input type="hidden" name="token" value="<?php echo h($_SESSION['token']); ?>">
                </form>
            </div>
        </div>
    </body>
</html>

config.php
    define('DSN', 'mysql:host=(ホスト名);dbname=(データベースの名前)');
    define('DB_USER', '(ユーザーネーム)');
    define('DB_PASSWORD', '(パスワード)');

    define('SITE_URL', '(サイトのURL)');
    define('ADMIN_URL', SITE_URL.'admin/');

    error_reporting(E_ALL & ~E_NOTICE);

    session_set_cookie_params(0, '/contact_php/');
?>

functions.php
    function connectDb() {
        try {
            return new PDO(DSN, DB_USER, DB_PASSWORD);
        } catch (PDOException $e) {
            echo $e -> getMessage();
            exit();
        }
    }

    function h($s) {
        return htmlspecialchars($s, ENT_QUOTES, "UTF-8");
    }

    function setToken() {
       /* 処理 */
    }

    function checkToken() {
       /* 処理 */
    }
?>

データベースはMySQLを使用し、定義は以下のとおりです。
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| name     | varchar(255) | YES  |     | NULL    |                |
| email    | varchar(255) | YES  |     | NULL    |                |
| memo     | text         | YES  |     | NULL    |                |
| created  | datetime     | YES  |     | NULL    |                |
| modified | datetime     | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

以上です。
なお、config.phpのdefineには正しい情報が記入されているものとします。
また、setToken()とcheckToken()はfunctions.php内に正しく記入されているものとします。
もちろん、冒頭の「<?php」も正しく記入されているものとします。

解答よろしくお願いします。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+1

PHPには詳しくないのですみませんが、質問の内容を見る限りはデバッグするのが近道だと思います。

DBにexecuteする直前の値を確認し、問題なければ直後にDBから値を取得してください。
そこまで切り分けが出来てからもう一度ご質問をお願いします。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/02/01 11:41

    $email = $_POST['email'];
    $memo = $_POST['memo'];
    とした後に var_dump($email); var_dump($memo); を行った所、しっかりと値は格納されていました。

    しかし、エラーチェック(3つのif文の羅列)をし、$paramsに格納をした直後に var_dump($params); を行った所、値は格納されていませんでした。
    どうやら、この辺で躓いてるようです。
    ありがとうございました。

    キャンセル

+1

私もPHP経験が浅いですが・・・
$sql = "insert into entries
                    (name, email, memo, created, modified)
                    values
                    ('{$name}', '{email}', '{memo}', now(), now())";
これでも行きませんか?

あと、IDがNot NullなのにデフォルトがNULLってのもちょっと気になりますね・・・。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/02/01 11:25

    上記の方法を試し、emailとmemo(本文)にもデータが格納されるようになりましたが、格納されたデータが「{email}」と「{memo}」になってしまいます。
    試しに{$email}と{$memo}にしましたが、こうすると値が格納されなくなります。

    データベースの定義ミス(NOT NULLなのにデフォルトがNULL)は先ほど気づいたので直しました汗 ありがとうございます。

    朝早くからご回答有難うございます。もう少し模索をしてみます。

    キャンセル

check解決した方法

0

自己解決しました。回答していただいたお二方、ありがとうございました。

以下のコード部分
if($email = '') {
      $error['email'] = 'メールアドレスを入力してください';
}
        
if($memo = '') {
      $error['memo'] = 'お問い合せ内容を入力してください';
}

$email=''

!isset($email)
にしたら正常に格納されました。
理由はよく分かりません。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/02/02 01:23

    if(!$email)でも行けると思う。
    issetだけだと漏れが出るはず。

    nullなのかブランクなのかを全て網羅するにはis_nullとissetと合わせた方が良いと思いますよ。

    キャンセル

  • 2015/02/02 10:23

    >>if(!$email)でも行けると思う。
    そうなのですか! それは初耳です!

    is_nullとissetを組み合わせる方法については、調べた限りだとかなり簡単に実現できることがわかったので、この方法でも書いてみます。
    ありがとうございます。

    キャンセル

  • 2015/02/02 18:17

    私は実はif(!$text)があまり信用出来ない(nullなのか0なのかブランクなのかの判定が不透明なので。)下記のようなファンクション作ってます。

    function nullCheck($text) {
    if ((is_null($text) || (empty($text) || (!isset($text))) {
    return false;
    }
    return true;
    }

    キャンセル

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

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

関連した質問

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