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

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

ただいまの
回答率

88.81%

データーベースにPHPで入力された情報を保存したい

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 429

Cherry1217

score 21

PHPで変数に保存されたデータをデーターベース上に保存したいのですが、方法が分かりません。
データーベースはMYSQLを使用しています。

  • 最終的にやりたい事
    Web上で入力された情報をデーターベースに保存し、その情報をWeb上に反映させる
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="description" content="タスク">
  <title>タスク</title>
</head>

<body>

  <form method="POST">
  <h>タスクを入力します</h>
  <p><input type="text" name="text" size="70"></p>
  <p><input type="submit" value="タスクを追加する"></p>
  </form>

<?php

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1 );


//postなら保存処理を行う
  if(!isset($post['text']))
  $errors['text'] = 'タスクを入力してください。';
else{
  $name = $_post['text'];
}

//textにデータが入っていた場合は、日付を登録する
if(isset($post['text'])){
  $Registered_Date = data("yyyy/mm/dd");
}else{
  $errors = 'タスクを入力してください';
}

try{

  $dsn='mysql:dbname=morning glory;host=127.0.0.1';
  $user='root';
  $password='root';

  $pdo = new pdo($dsn,$user,$password);

  $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

//エラーがなかった場合、データーベースにデータを保存する
  if(count($errors) === 0){
    $sql1 =//$name $Registered_Dateで保存された情報をデーターベースに保存する
  }


  $stmt = $pdo->query($sql1);

 foreach( $stmt as $value ) {
     echo $value['task'];
}
}catch (Exception $e){
 echo 'エラーがありました';
 echo $e->getMessage();
 exit;

}

?>

</body>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

「Web上で入力された情報をデーターベースに保存し、その情報をWeb上に反映させる」
というシステムの中で、どう機能を分割して作っていくかをしっかり考える必要があります。
例えば、

1.フォーム入力用のページを表示する。
2.フォーム入力によって送信されてきたデータをデータベースに反映する。
3.データベースからデータを引き出して表示する。

の3つがあるように見えます。
これらを、一つのphpファイルで実現するのか、それぞれ独立したhtmlファイルやphpファイルで実現させるか、
を検討します。

ここでは、一つのphpファイルで実現するとしましょう。
一つの中に3つの処理を破綻せず詰め込むためには、処理の順番が肝心です。

・フォーム入力を受信してた場合に、データを検証してOKならデータベースに反映する。
・フォーム入力枠表示する。フォーム入力を受信してた場合に、NGだった場合にはフォーム入力欄にデータを表示しつつエラーメッセージも表示する。
・(フォーム入力があろうともなかろうとも)データベースからデータを引き出して表示する。

みたいな流れが妥当でしょうか。

冒頭でデータベースへのコネクションを確立しさえすれば、
データベースに反映する場面と
データを引き出す場面とで共通してコネクションを使い回せます。

この流れでphpファイル上の処理を見直しをしてみてください。

それとは別に、
データベースにアクセスできているかを簡単にテストしてください。
いきなり上に掲げた処理を作っても、多数の問題を抱えていてはどこから手を付けていいかわからなくなります。
確実に動く、使える処理を揃えてから、組み合わせていきます。
下記は、データベース接続だけを試すコードです。

<?php

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1 );

try{

    $dsn = 'mysql:dbname=morning glory;host=127.0.0.1;charset=utf8mb4';
    $user = 'root';
    $password = 'root';

    $pdo = new pdo($dsn, $user, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => false
    ]);


}
catch (PDOException $e) {
    header('Content-Type: text/plain; charset=UTF-8', true, 500);
    exit($e->getMessage());    
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="description" content="タスク">
  <title>タスク</title>
</head>
<body>
    <p>接続成功.</p>
</body>
</html>


ポイントは、データベース接続で例外が発生した場合に
すでにhtml出力してしまうと正しく情報を出力する妨げになりうるため、
データベース処理部分のあとにHTMLのヘッダーやら本体やらを置いていることです。
フォーム入力をデータベースに反映する場合にも
この組み方を真似すると良いでしょう。

次に、データベースにデータを格納できるかどうかをテストします。

<?php

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1 );

try{

    $dsn = 'mysql:dbname=morning glory;host=127.0.0.1;charset=utf8mb4';
    $user = 'root';
    $password = 'root';

    $pdo = new pdo($dsn, $user, $password, [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => false
    ]);

    $stmt = $pdo->prepare('INSERT INTO tasks("name", "registered_date") VALUES (:name, now());');
    $pdo->beginTransaction();
    try {
        $stmt->bindValue(':name', 'sample text', PDO::PARAM_STR);
        $stmt->execute();
        $pdo->commit();
    }
    catch (PDOException $e) {
        $pdo->rollBack();
        throw $e;
    }

}
catch (PDOException $e) {
    header('Content-Type: text/plain; charset=UTF-8', true, 500);
    exit($e->getMessage());    
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="description" content="タスク">
  <title>タスク</title>
</head>
<body>
    <p>データ格納成功.</p>
</body>
</html>


みたいな。

丁寧にbeginTransaction()とか書く習慣を身に着けておくと良いです。
たまたま今回は一つのテーブルにデータを保存するだけかもしれませんが、
規模が大きくなってくると複数のテーブルにデータを書き込むことになり、
書き込んでいる途中でエラーが生じた場合に、
書き込む前の状態まで巻き戻す(rollback()する)必要があります。
その練習だと思って書きました。

データベース処理のその先については
PHPでデータベースに接続するときのまとめ - Qiita
を折りに触れて読み返すことをおすすめします。

フォーム入力の検証については、
流行り(?)のfilter_input()を使うとよいかと。
$name = $_POST['text'];

$name = filter_input(INPUT_POST, 'text');
とすることで、POST受信していなければ文字列長ゼロの文字列になりますし。
もちろん、そのあと$nameにふさわしくない文字が含まれているかどうかを検証する処理は必要です。
(へんな記号は使いたくないとか、そこは自分で仕様を決める部分ですが。)

ここでは伝えきれないことも多々あるので、
細かな場面毎の使える技術の積み重ねを心がけてください。

老婆心ながら、
フォーム上ではtext、
php上の変数名がnameとなるのは、
規模が大きくなってくるといちいち場面毎に
どこになんのデータが入っているかを対照表を作らなきゃならなくなるので、
なるべくフォーム上も変数名もテーブル上のカラム名も同じ名称を使うようにするべきかと。
使えない場合でも簡単に類推できるようでないと、
後々自分の首を絞めます。
(数カ月後にテコ入れしようとした場合とか忘れてる。)

さらに老婆心ながら、
日付らしきデータを
$Registered_Date = data("yyyy/mm/dd");
で作っているようですが、
日付時刻データを文字列で処理するのはナンセンスです。
具体例としては、
・日付や時刻の足し算引き算、
・2つの日付や時刻の差を求めるとき、
など大変なので、
php上ではDateTimeクラスなど、
データベース上ではDATE型TIMESTAMP型を使います。
php内で特に処理しなくても、
データベース上で使えるnow()関数があります。
一度ご自身で調べてみてください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

色々つっこむところはありそうに思いますが、取り急ぎ、$_POSTです。
変数は大文字小文字を大別するので正確に。はじめのうちはPHPマニュアルからコピペするくらいがちょうどいいです。
※今は入力値の検証もできるfilter_input()を使うのが主流になってきています

エラー表示はONにされているようですが、エラーメッセージ確認しましたか?変数未定義・または配列のindexエラーが出ているはずです。
特に学習段階や開発途中はエラーメッセージが問題解決・問題切り分けのヒントになります。

下記のような記事は必ず目を通しておいてください。


質問するときのヒント」は読んでほしいのですが、「起きている問題(エラーメッセージ)」「聞きたい事」「要件」は具体的に記載してください(はじめのうちは質問テンプレートを利用するのが良い)
質問は編集できる、、ということも覚えておいてください(この質問からやってみてください)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/03 10:56

    ご回答ありがとうございます。
    もう一点訪ねたいのですが、
    if(count($errors) === 0){
    $sql = "select task
    from task_information
    where task = 'テスト';";
    }
    の一番最初の行で「Notice: Undefined variable: errors in /Applications/MAMP/htdocs/PHP/index.php on line 43」
    変数が未定義だと言われてしまうのですが、「$errors」という変数を定義しているにも関わらず
    エラーとして表示されてしまう理由がわかりません。
    ヒント等いただけると助かります。

    キャンセル

  • 2019/05/03 11:02

    定義されないパターンがあるからですね。
    ifなどで分岐させてますよね。
    分岐などなにもないところで確実に初期化した変数を定義してください。

    キャンセル

  • 2019/05/03 11:19

    横から。
    $errors['text'] = 'タスクを入力してください。';

    $errors = 'タスクを入力してください';
    って見つけるけど、そもそも$errorsを初期化してないからだよね。

    キャンセル

  • 2019/05/03 11:37

    ちょこちょこ直すよりいったん造り直してもいいかもしれませんね。
    CRUDの基本形なので自分できちんと全て理解できるまで何度も作り直しても読み直してしたほうが身に付きます

    キャンセル

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

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

関連した質問

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