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

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

ただいまの
回答率

87.61%

index.htmlで入力したアンケートデータがphpMyAdminのテーブルに保存されない(出典:「いきなりはじめるPHP」)

受付中

回答 2

投稿 編集

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

score 23

前提・実現したいこと

今回は「いきなりはじめるPHP ワクワク・ドキドキの入門教室」からの質問です。

単刀直入に言うと、本書のp122~125「アンケート自動保存機能を追加しよう!」で詰まっています。

具体的には、入力したアンケートデータがphpMyAdminのテーブルに来ないのです。
本書で言えばp125のように「解答を入力して、サンクスページまで進む」→「アンケートデータが(phpMyAdminのテーブル「anketo」内)に保存される」のようにしたいのですが、現在「解答を入力してサンクスページまで進めることはできるが、アンケートデータば保存されない」といった状態です。

現在の状況

最初に、「thanks.php」のコードを置いておきます。
SQL起動のコードは、以下のホームページより、「パスワードも入力しないとphpMyAdminに接続できない」という意見を参考にしています。
https://royal-fummy.com/blog/php-startup-with-mamp/

<!DOCTYPE html>
<html lang="ja">
<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>PHP基礎</title>
</head>
<body>

<?php

  // phpMyAdminに接続する

  $dsn='mysql:dbname=phpkiso;host=localhost;charset=utf8';
  $user='root';
  $password='root';
  $dbh=new PDO($dsn, $user, $password);

  ini_set('error_reporting', E_ALL);

  $postNN = $_POST['nickname'];
  $postEMAIL = $_POST['email'];
  $postCOMMENT = $_POST['comment'];

  $postNN = htmlspecialchars($postNN);
  $postEMAIL = htmlspecialchars($postEMAIL);
  $postCOMMENT = htmlspecialchars($postCOMMENT);

  echo $postNN;
  echo 'さん'.'<br>';
  echo 'ご意見ありがとうございました!';
  echo '<br>';
  echo '頂いたご意見『';
  echo $postCOMMENT;
  echo '』';
  echo '<br>';
  echo $postEMAIL.'にメールをお送りしたのでご確認ください。';

  $mail_sub = 'アンケートを受け付けました。';
  $mail_body = $postNN."様へ/nアンケートご協力ありがとうございました。";
  $mail_body = html_entity_decode($mail_body,ENT_QUOTES,"UTF-8");
  $mail_head = 'From: xxx@xxx.co.jp';
  mb_language('Japanese');
  mb_internal_encoding("UTF-8");
  mb_send_mail($postCOMMENT,$mail_sub,$mail_body,$mail_head);

  $sql='INSERT INTO anketo(nickname,email,comment) VALUES("'.$postNN.'","'.$postEMAIL.'","'.$postCOMMENT.'")';
  $stmt=$dbh->prepare($sql);
  $stmt->execute();

  $dbh=null;

 ?>

</body>
</html>

次に、ファイルの構成です。
このファイル内で、それぞれ「check_2.php」が「index.html」、「ifset.php」が「check.php」にあたります。「thanks.php」は本書と同じです。

input -----------$ ls
check_2.php    ifset.php    input.php    thanks.php

phpMyAdmin
イメージ説明

データベース名は「phpkiso」、テーブル名は「anketo」です。

試したこと

基本的に本書の通りにコードは入力したので、スペルやクォーテーションのチェックを行いました。
ただし、クォーテーションは変えてしまうとサンクスページ自体表示できなくなってしまいます。
google検索も試しましたが、本書でつまずいた内容が乗っていることは少なく、目当ての情報も見つかりませんでした。

最終目標

冒頭でもあげた通り、解答を入力してサンクスページまで進んだ後、サンクスページにまで来たデータを「code」2番目のデータとしてテーブルに追加されるようにすることです。
要は、「アンケート回答者がフォームから送ってきた解答をphpMyAdminで管理できるようにする」ことが最終目標です。

補足情報(FW/ツールのバージョンなど)

OS:mac
ブラウザ:chrome(最新のバージョン)
テキストエディタ:atom(ver:1.32.2)
サーバー:MAMP(free)5.2
以下、MAMP内の情報
PHP:7,1.12
mySQL:5.7.23

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • m.ts10806

    2019/01/30 10:36

    はい。回答にも書きましたが、書籍のPHPのバージョンと実際にご自身が動かされているPHPのバージョンは違うはずです。ということは書籍のPHPのバージョンで動いているはずの機能が動かない可能性があります。
    非推奨になったり削除になったりしている機能を使っている可能性もあります。
    最低でもPHP7以上対応の書籍にした方が良いです。
    当該書籍購入の際にネットで参考にしたのがどのような記事かは存じ上げませんが、PHP7対応の書籍を紹介しているとは限らない(あくまで「入門書の紹介」レベル)ので、実際に本屋さんに赴いた方が良いようには思います。
    「PHP7対応 書籍」で検索するとそれなりに出てきます。ただネット上やamazonなどでは項目までしか分からないのでできれば中身を立ち読みできそうな場所に赴いてみたほうがいいですね・・

    キャンセル

  • kaoru-drosera

    2019/01/30 10:43

    ありがとうございます。
    私の無学をどうかお許しください…。

    キャンセル

  • m.ts10806

    2019/01/30 10:49

    いえ、誰も入門時はわけわからない状態かと思います。こういった技術は日進月歩なので最新の情報が良いのは当然で、書籍が悪いとは言いませんが、書籍が出た時点では既に古い情報になっている可能性も高いです。
    最初から全て対応するのは難しいにしろ、セキュリティ対策への言及がきちんとしてある書籍を選ぶか、Qiitaなどで新しい記事、評価の高い記事を参考にするようにされた方がいいかもしれません。
    あとphpであればphpマニュアル(マニュアルと名はついてますがWebサイトです)は必読です。
    辞書がわりにもなりますし、私も回答に散りばめているようにteratailでの回答の根拠資料にも頻繁に使われます。

    キャンセル

回答 2

+3

この内容だけだと再現確認が難しいですし、問題の切り分けも出来ません。
DBに関する処理を行うときは、言ってしまえば外部の仕組みを使うわけですから、
try-catchを利用して異常を検知するようにしてください。
基本的に、ですがPHPの構文としてまずいことがない限り外部の仕組みのエラーは
error_reportingの設定では感知できないことが殆どです。

<!DOCTYPE html>
<html lang="ja">
<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>PHP基礎</title>
</head>
<body>

<?php

// データベースに接続する
try{

    $dsn='mysql:dbname=phpkiso;host=localhost;charset=utf8';
    $user='root';
    $password='root';
    $dbh=new PDO($dsn, $user, $password);

    ini_set('error_reporting', E_ALL);

    $postNN = $_POST['nickname'];
    $postEMAIL = $_POST['email'];
    $postCOMMENT = $_POST['comment'];

    $postNN = htmlspecialchars($postNN);
    $postEMAIL = htmlspecialchars($postEMAIL);
    $postCOMMENT = htmlspecialchars($postCOMMENT);

    echo $postNN;
    echo 'さん'.'<br>';
    echo 'ご意見ありがとうございました!';
    echo '<br>';
    echo '頂いたご意見『';
    echo $postCOMMENT;
    echo '』';
    echo '<br>';
    echo $postEMAIL.'にメールをお送りしたのでご確認ください。';

    $mail_sub = 'アンケートを受け付けました。';
    $mail_body = $postNN."様へ/nアンケートご協力ありがとうございました。";
    $mail_body = html_entity_decode($mail_body,ENT_QUOTES,"UTF-8");
    $mail_head = 'From: xxx@xxx.co.jp';
    mb_language('Japanese');
    mb_internal_encoding("UTF-8");
    mb_send_mail($postCOMMENT,$mail_sub,$mail_body,$mail_head);

    $sql='INSERT INTO anketo(nickname,email,comment) VALUES("'.$postNN.'","'.$postEMAIL.'","'.$postCOMMENT.'")';
    $stmt=$dbh->prepare($sql);
    $stmt->execute();
    $dbh=null;

}catch(PDOException $e){
    var_dump($e);
}

teratail:PHP、PDOの例外処理について

ただ、この処理内容は他にもよくないところが幾つもあります。
「必ず成功する前提」のプログラムはかなり危険です。何かで失敗することを前提で、その対策を適宜してください。

  1. mb_send_mail()より前に「メールを送りました」と文言を出している
    メール送信成功するかどうか分かりませんよね。せめて返り値(bool)を確認してから画面表示しましょう。
  2. ↑と同様、DB登録も成功するかどうか分かりません。正否確認をしてから画面表示しましょう。
  3. pdo利用しているのに一切エスケープせずにそのままSQL文に突っ込んでいる。
    SQLインジェクションの概念を学んでください。
    PDOでしたらbindValueなどを活用しましょう。

蛇足:
ご提示の書籍、調べたところ2011年発売ですよね?
今PHP7.1.12でされているのでしたらPHPのバージョン合わないと思いますし、当時でているPHPのバージョンは基本的に軒並みサポート終了しているはずなので、入門とはいえ、あまりそのままで進めないほうがいいように思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+3

この本、ダメだわ。

1.htmlspecialchars()でHTML出力用に加工した文字列をデータベース保存に使ってるのは悪手。
POSTされた文字列を書き換えずにhtml表示のところだけ使えばいいのに。

2.INSERT文を文字列連結で作ってるので、SQLインジェクションされても笑えない。
prepare()→bindValue()→execute()の3段階踏むやり方のサンプルを探して直したほうがいい。

3.mb_send_mail()を使ってのメール送信は送信できるようにするまで
様々な点検項目があって簡単にはいかない(phpからのメール送信ネタをteratailで見ない日がない)から
メール送信にこだわらないのなら棚上げすることを推奨。


進展がないようなので、基本的なところから。

PHPのエラー表示設定について \- Qiita
webブラウザ上にエラー表示できるようにしつつ、
MAMPのapache httpdが記録するエラーログもチェックする。
MAMP \- Apache/MySQL/PHPのエラーログファイルの場所(フルパス) \- PC設定のカルマ

phpからのデータベースアクセスが、
何らかの理由で拒否・無視されているだろうから、
エラーログを頼りに設定を変更するとかデータベースを直すとか
手を考えなきゃいけないわけで、
そういうエラーを特定しうる情報がないと
進展しないわけで。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/29 16:19

    この手の入門書でそこまで考慮されて書かれているのを見たことないですよね。

    キャンセル

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

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

関連した質問

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

  • トップ
  • PHPに関する質問
  • index.htmlで入力したアンケートデータがphpMyAdminのテーブルに保存されない(出典:「いきなりはじめるPHP」)