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

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

ただいまの
回答率

88.62%

MYSQLとPHPの問題か、どうしてもreserveslotがアップデートされない

解決済

回答 3

投稿 編集

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

phpsyoshinsya

score 105

いま困っていること

関数updtrsによって、予約枠管理テーブルで、予約された日の予約枠に予約済みである1をアップデートして設定したい。
エラーはない物の、テーブルreserveslotがアップデートされない。

関連ソース

// 予約日時を出力する
function product_reserve_time(){
    // データベースに接続
    $db = new mysqli("localhost", "mrt", "abcdefgh", "mrt");
    $db -> set_charset("sjis");
    // テーブルtodayのdate(最終更新日のタイムスタンプ(整数型))より以降のレコード数を抽出
    $result = $db -> query("select*  from today");
    print $db -> error;
    // 抽出したリソースハンドらーから番号配列(0から始まる配列)で一行を受け取る
    $row = $result -> fetch_assoc();
    // $today=(string)$row["date"];
    $result = $db -> query("select count(*) from reserveslot where date>={$row['date']}");
    $row = $result -> fetch_assoc();
    // レコード数が0なら
    if($row["count"] == 0){
        // テーブルtodayから今日の日付を示すタイムスタンプ(整数型の秒単位の数値)を取得
        $result = $db -> query("select * from today");
        // 取得したリソースハンドラーから連想配列(名前参照型配列)で一行取得
        $row = $result -> fetch_assoc();
        // データベースからの値は全てstring(文字列形)なのでint(整数型)に直して保存
        // ここは関数の中なので$timeはローカル変数
        $time = (int)$row["date"];

        // テーブルreserve_infoに今日の日付を示すタイムスタンプを含むレコードを挿入query内で変数を使用するときは{}で囲むこと。値が文字列型なら'で囲むことも忘れずに。
        $db -> query("insert into reserve_info (date) values({$row["date"]})");
        print $db -> error;
        // $iを0に設定し++(+1)しながら6より小さい間{}の処理を行う。ここでは1週間分の日付のタイムスタンプを含むレコードを挿入している
        for($i = 0;$i < 6;$i++){
            // 1日分の秒数を加えた$timeの値を含むレコードを挿入
            $db -> query("insert into reserveslot (date) values('{$time}')");
            // $timeに1日分の秒数を加える。60*60*24=86400秒
            $time = $time + 86400;
            print $db -> error;
            }
        }
    // 今日を示すタイムスタンプを含むレコード数が0でなく、7よりもちいさいとき
    if($row["count"] != 0 && $row["count"] < 7){
        // レコード数を整数型に変換して保存
        $count = (int)$row["count"];
        // 1週間分に足りないレコードの数を計算し保存
        $count = 7 - $count;
        // テーブルreserve_infoに保存されている日付を表すタイムスタンプを含むレコードをタイムスタンプが保存されているdateカラム(列)を基準に降順にソート(並べ替えて)1レコードだけ抽出
        $result = $db -> query("select * from reserveslot order by date desc order by date desc limit 1");
        // 抽出したリソースハンドラーから連想配列(名前参照型配列)で1行取得
        $row = $result -> fetch_assoc();
        // 抽出したデータのdateの値をint(整数型)に変換して保存
        $time = (int)$row["date"];
        // $iを$countの値に設定し++(+1)しながら$countより小さい間{}の処理を行う
        for($i = 0;$i < $count;$i++){
            // $timeに1日分の秒数を加える。60*60*24=86400秒
            $time = $time + 86400;
            // 1日分の秒数を加えた$timeの値を含むレコードを挿入
            $db -> query("insert into reserveslot (date) values('{$time}')");
            print $db -> error;
            }
        }

    // テーブルtodayのdate以上のタイムスタンプを持つレコードをテーブルreserve_infoから昇順で7レコード抽出
    $result = $db -> query("select * from reserveslot where date>=(select date from today) limit 7");
    print $db -> error;
    // 抽出したリソースハンドラーから連想配列(名前参照型配列)で1行\ずつ取得し、$rowがnullでない間{}の処理を行う
    while($row = $result -> fetch_assoc()){
        // dateに相当するラジオボタンを出力し、dateをタイムスタンプとする月と日をidate関数を用いて取り出し明示的に表示をおこなう
        printf("<input type=\"radio\" name=\"date\" value=\"%s\">%s月%s日", $row["date"], idate("m", $row["date"]), idate("d", $row["date"]));
        // rsの値をname属性に持つセレクトボックスを作り表示する
        printf("<select name=\"rs\"><option>----</option>");
        // 予約枠1が0(未予約)なら選択肢として追加する以下7枠全てについて同様の処理を行う
        if($row["rs1"] == 0) print "<option value=\"1\">19:00</option>";
        if($row["rs2"] == 0) print "<option value=\"2\">20:30</option>";
        if($row["rst3"] == 0) print "<option value=\"3\">22:00</option>";
        if($row["rt4"] == 0) print "<option value=\"4\">23:30</option>";
        if($row["rs5"] == 0) print "<option value=\"5\">25:00</option>";
        if($row["rs6"] == 0) print "<option value=\"6\">26:30</option>";
        if($row["rs7"] == 0) print "<option value=\"7\">28:00</option>";
        // セレクトボックスの終了タグを出力
        print "</select><br><br>";
        }
    // データベースとの接続を終了
    $db -> close();
    }

// 約予約枠をテーブルreserveslotに登録する
function updtrs(){
    $query = "update table reserveslot set ";
    switch($_SESSION["time"]){
    case 7:
        $query .= "rs7=1 ";
        break;
    case 6:
        $query .= "rs6=1 ";
        break;
    case 5:
        $query .= "rs5=1 ";
        break;
    case 4:
        $query .= "rs4=1";
        break;
    case 3:
        $query .= "rs3=1";
        break;
    case 2:
        $query .= "rs2=1 ";
        break;
    case 1:
        $query .= "rs1=1 ";
        break;
        }
    $query .= "where date='" . $_SESSION["date"] . "'";
    $db = new mysqli("localhost", "mrt", "abcdefgh", "mrt");
    $db -> query("{$query}");
    $db -> close();
    }

追記コード
product_reserve_timeを呼び出したすぐ後のページで

if ($_POST["page3"]){
printf("time stamp=%s<br>rs=%s",$_POST["date"],$_POST["rs"]);


ここで、rs値が----になって帰ってきます。
これがアップデートに失敗する原因のような気がしてなりません。

なにか参照方法が間違っているのでしょうか?

考えられる原因と実装したい機能

テーブルnotes(予約の詳細情報が格納される)には予約枠欄に予約済みの予約枠1-7が繁栄されている。

しかし、一度予約した同一日同予約枠が再度表示されてしまう。

関数updtrs内に問題があるように思えるが、SQLとPHPのどちらに問題があるのか、絞り込めていない。
一度予約が入ると、
その予約枠に他の予約が重複すると困る事象が発生する。

これを回避するために、テーブルreserveslotを作成したが、
どうもうまく活用できていないことを解決すると、とりあえずプロジェクトのうち一つが完成する。

お願い

全く目が見えないため、
URLだけの提示はご遠慮いただきたく、
修正箇所が把握しやすいよう、元のソースも併記していただけますようご理解とご協力お願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • phpsyoshinsya

    2018/11/16 09:55

    それは、つまりTeraTailは懐が深いよっていうご指導ですか?

    キャンセル

  • Zuishin

    2018/11/16 10:47

    「貧乏だからおごって」と毎回言ってくる人と飲みに行きたいですか? いつもはちゃんと払う人がたまたま飲みすぎて困っているときにおごるのは気にならなくても、貧乏だから助けてもらうのが当然と思っている人を助けるのは面倒になりませんか? リンクするのは、それが必要だからです。リンク先がまともに読めない状態の場合もあるでしょうから、その時には助けてと言えばいいと思いますが、人より数分時間がかかるだけなら自分で読んでください。

    キャンセル

  • phpsyoshinsya

    2018/11/17 04:55

    まったく関係のないお答えですみません。timestampはポストで返ってきていますが、rs値が----になっていることが判明しました。出力のなにがわるいのでしょうか?

    キャンセル

回答 3

checkベストアンサー

+2

updateのSQLもちょっと違うような気が。。

$query = "update table reserveslot set ";
↓
$query = "update reserveslot set ";

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/16 11:50

    ありがとうございます。

    キャンセル

  • 2018/11/17 05:12

    質問を編集しましたので、どうかご一読ください。

    キャンセル

  • 2018/11/19 10:13

    追記コードの方確認しました。
    UPDATEのSQLは$_SESSION["time"]、$_SESSION["date"]などから生成されているようなので、あまり関係は無いような気がします。。

    以下のような感じで一度updtrsで生成されたSQLや値をチェックして原因を追いかけてみてはいかがでしょうか。

    echo $query;
    var_dump($_SEEEION);

    キャンセル

+1

関係あるかどうかわかりませんが、以下そもそものコードが間違っていませんか?

1.rs1-7を変数に利用していると思うが、変数名が一部異なる。
2.rs4の場合に$queryに対し、SQL組立時に連結ではなく代入している。

 元コード

        if($row["rst3"] == 0) print "<option value=\"3\">22:00</option>";
        if($row["rt4"] == 0) print "<option value=\"4\">23:30</option>";
...
    case 4:
        $query = "rs4=1";
        break;

 想定した正しいコード

        if($row["rs3"] == 0) print "<option value=\"3\">22:00</option>";
        if($row["rs4"] == 0) print "<option value=\"4\">23:30</option>";
...
    case 4:
        $query .= "rs4=1";
        break;

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/16 01:40

    なるほど、
    言われてみればそうですね。

    $query.="rs4=4";
    じゃないといけないですよね。
    ご指摘ありがとうございます。
    音声読み上げソフトで記号は全て読み上げるに設定していましたが、私の聞き漏らしですね。

    キャンセル

  • 2018/11/17 05:16

    ご指摘いただいた点を直してもだめだったので、ちょっとエラー処理を入れてみたところ、$_POST["rs"]の返り値が----になっています。
    これも一つのアップデートがうまくいかないげんいんかと。詳しくは質問を編集しましたので、どうかご一読ください。

    キャンセル

+1

sqlは100%成功するわけではないというところを念頭に置かれた方が良いです。
query結果の成功可否を見てmysqli_error()を確認するとかはもちろんですし、
DBに何かしら干渉する処理を書く場合はtryーcatchで異常検知の仕組みを導入するのが通例です。
それだけでも今悩まれてることの多くは解決できそうに思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/16 01:25

    try catchやpdoは書き方さえ覚えればクラスなどは読み込まなくても利用できますか?
    やりたいことを提示して、
    pdoで書くとというのを
    是非教えていただければ、
    今回から採用できるかもしれません。

    キャンセル

  • 2018/11/16 01:34

    pdoについては今回は触れてないのでここで急にpdoが出てくるのが疑問ですけど、DBの操作についてはtry-catchを使っていない記事の方が少ないですしQiitaの記事を探すかphpマニュアルの例文を参考にすることから始めると良いかと。

    昨今、オブジェクト指向を採用しないというのはあり得ないのでなぜ「クラスなどは読み込まなくても」というこだわりを条件として出されるのか分かりません。

    キャンセル

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

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

関連した質問

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