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

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

ただいまの
回答率

88.92%

SELECT文とパラメータの引き継ぎ

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,826

yutaishikawa_

score 54

前回に引き続き、質問させていただきます。
現在タスク機能付きのカレンダーを作成しているところでして、SELECT文でMySQLからカラムを表示しようとしたところ、中々うまくいきません。

方法として、$taskという変数と、$taskDataという連想配列を準備し、
$rowにテーブル情報を格納。
最後に、$taskという変数に<td></td>という処理をもたせ、ループすることで、タスクありの日付をカレンダーから選択されたときに、その日のテーブル情報を引っ張ってこれるのではないかと思っておりました。
↓画像の<tabale>タグに、index.phpで作成しているカレンダーの日付に格納されている情報を表示したく思っております。
イメージ説明
あと、もう少しな気がするのですが、知識不足でつまづいてしまいました。
具体的な表示方法等(記述)がありましたら、ご指導宜しくお願い致します。

<?php
require_once('dbconnect.php');
// 年月日のパラメータを取得する。
$ymd = isset($_GET['ymd']) ? $_GET['ymd'] : date("Y-m-d");
$task = "";
// タスクの配列を準備
$taskData = array();
// PHP->MySQLtable
// タスクのパラメータを送れるようにする。
$query = $mysqli->query(" SELECT * FROM tasks WHERE task_date = '$ymd' ");
    // エラー処理
    if (!$query) {
        die('クエリーが失敗しました。'.mysql_error());
    }
    // 日ごとにタスクを取得
    while ($row = $query->fetch_assoc()) {
        $taskData[] = array(
        'id'=>$row['id'],
        'title'=>$row['title'],
        'task_date'=>$row['task_date'],
        'place'=>$row['place'],
        'memo'=>$row['memo']
        );
    }
    if (isset($taskData[$row])) {
        // 結合代入演算子を使用して、<td>を取得。配列の箱が完成。
        $task .= str_repeat('<td></td>', 5);
        $tasks = '<td>'.$row.'</td>';
        // タスクを初期化
        $task = "";
    }
?>
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<title>Today | タスク一覧</title>
<table border="1">
    <thead>
    <tr>
        <th>タイトル</th>
        <th>日時</th>
        <th>場所</th>
        <th>メモ</th>
    </tr>
    </thead>
    <tbody>
    <?php
        echo $task;    
    ?>
    </tbody>
</table>
    <p><a href="index.php">追加画面に戻る</a></p>
</html>


追記:皆様ご回答ありがとうございます。まとめてみたところ、以下のような記述となりました。
ですが、表示はされません。


<?php
require_once('dbconnect.php');
// 年月日のパラメータを取得する。
$ymd = isset($_GET['ymd']) ? $_GET['ymd'] : date("Y-m-d");
// タスクの配列を準備
$task = "";
$taskData = array();
// PHP->MySQLtable
// タスクのパラメータを送れるようにする。
$query = $mysqli->query(" SELECT * FROM tasks WHERE task_date = '$ymd' ");
    // エラー処理
    if (!$query) {
        die('クエリーが失敗しました。'.mysql_error());
    }
while ($row[] = $query->fetch_assoc()) {
    // 各メンバ取得
    $taskData[] = array(
    'id'=>$row['id'],
    'title'=>$row['title'],
    'task_date'=>$row['task_date'],
    'place'=>$row['place'],
    'memo'=>$row['memo']
    );
    // タスクを表示形式に設定
    $task .= "<td>".$row."</td>";
}
?>
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<title>Today | タスク一覧</title>
<table border="1">
    <thead>
    <tr>
        <th>タイトル</th>
        <th>日時</th>
        <th>場所</th>
        <th>メモ</th>
    </tr>
    </thead>
    <tbody>
    <?php foreach ($taskData as $row): ?>
        <tr>
            <td><?= htmlspecialchars($row['title']) ?></td>
            <td><?= htmlspecialchars($row['task_date']) ?></td>
            <td><?= htmlspecialchars($row['place']) ?></td>
            <td><?= htmlspecialchars($row['memo']) ?></td>
        </tr>
    <?php endforeach;  ?>
    </tbody>
</table>
    <p><a href="index.php">追加画面に戻る</a></p>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 4

+2

次のような書き方が良く使われています。

<table border="1">
    <thead>
    <tr>
        <th>タイトル</th>
        <th>日時</th>
        <th>場所</th>
        <th>メモ</th>
    </tr>
    </thead>
    <tbody>
    <?php foreach ($taskData as $data): ?>
        <tr>
            <td><?= htmlspecialchars($data['title']) ?></td>
            <td><?= htmlspecialchars($data['task_date']) ?></td>
            <td><?= htmlspecialchars($data['place']) ?></td>
            <td><?= htmlspecialchars($data['memo']) ?></td>
        </tr>
    <?php endforeach; ?>
    </tbody>
</table>

htmlspecialchars は場合によっては第3引数まで指定しないと脆弱なことがあるので注意)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/10 12:42

    ご回答ありがとうございます。
    私の乏しい知識から推測するに、foreach():endforeach;で$tadkDataのarray()から各要素から取り出す処理で、それをhtmlspecialcharsでHTMLエンティティに変換して表示している。という認識なのですが、お間違いありませんでしょうか。
    日々勉強しているのですが、未だにわからないことが多いので、非解釈するのに非常に手間がかかってしまい、申し訳ありません。

    ちなみに$dataなのは何か理由(変数の例で使われることが多い)などございますのでしょうか?

    キャンセル

  • 2015/07/10 13:47

    > foreach():endforeach;で~~

    その通りです。

    > ちなみに$dataなのは~~~

    ShunsukeIzui さんの回答からコピペしたからです、特に理由はありません。

    キャンセル

  • 2015/07/10 17:14

    かしこまりました。
    また一つ、実用的な知識を得ることができました。
    ご回答ありがとうございました。

    キャンセル

checkベストアンサー

+1

まず仕様についてですが、おそらくカレンダーに予定事案等が投稿された場合に、カレンダーの日付等をクリックすると、該当日の詳細予定が表示される物だと推察いたします。

本質問案件は、詳細予定一覧表示画面の内容と見受けます。

質問事項は、DBから該当日付のデータを取得し、1予定=1行にして並べる際に、1件も表示されないということかと存じます。

また、本案件は練習課題について質問されておられると認識しております。
よって、虚弱性等についての記述は省略しています。


while文の中でデータを取得し、$taskDataバッファに詰めておられますが、
while文の後のif文で$taskDataから詰めたデータを取り出していないため、表示されません。

また、$taskに、<td>タグ等詰め込むことで、HTML部分に極力PHPの記述をしない意図があるかと存じます。

そこで、下記のような、while文の中で$task に詰め込むようにされてはいかがでしょう。
(while文の下のif文は削除)


while ($row = $query->fetch_assoc()) 
{
    // 各メンバ取得
    $id = $row['id'];
    $title = $row['title'];
    $task_date = $row['task_date'];
    $place = $row['place'];
    $memo = $row['memo'];

    // タスクを表示形式に設定
    $task .= "<tr><td>${title}</td><td>${task_date}</td><td>${place}</td><td>${memo}</td></tr>";
}

■デバック用
下記のように、$row,$task の値を確認してみると、どこに原因があるのか掘り下げることが出来ます。
少なくとも、全く何も表示されない状態だとしたら、DBからデータを取るためのどこかに不備があります。
※データ取得が出来ないため、while文の中に入らず$task="" の状態で抜ける。

while ($row = $query->fetch_assoc()) 
{
    // 各メンバ取得
    $id = $row['id'];
    $title = $row['title'];
    $task_date = $row['task_date'];
    $place = $row['place'];
    $memo = $row['memo'];

    // タスクを表示形式に設定
    $task .= "<tr><td>${title}</td><td>${task_date}</td><td>${place}</td><td>${memo}</td></tr>";
}

var_dump($task);
var_dump($row);


投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/10 17:54

    ご回答ありがとうございます。

    $query で var_dumpしてみたところ、
    object(mysqli_result)#2 (5) { ["current_field"]=> int(0) ["field_count"]=> int(5) ["lengths"]=> NULL ["num_rows"]=> int(17) ["type"]=> int(0) }
    というデータが取れました。

    ヒットするデータはある状態だとおもうのですが、やはり、正しく指定できていないということでしょうか。

    キャンセル

  • 2015/07/10 20:13

    <?php
    $query = $mysqli->query(" SELECT * FROM tasks");
    // エラー処理
    if (!$query) {
    die('クエリーが失敗しました。'.mysql_error());
    }
    while ($row[] = $query->fetch_assoc()) {
    var_dump($row);
    }
    ?>

    はどうなりますか?

    キャンセル

  • 2015/07/13 08:30

    リプライ遅れてしまいました。
    $rowをvar_dumpしたところ、tableであるtasksからカラムを取得できていたのを確認しました!
    この値を全て、
    $taskData[] = array(
    'id'=>$row['id'],
    'title'=>$row['title'],
    'task_date'=>$row['task_date'],
    'place'=>$row['place'],
    'memo'=>$row['memo']
    );
    で$row['']に格納し、
    $task .= $taskData;
    という処理を書いていた限り処理がまったく動作することはありませんでした...

    キャンセル

+1

表示の仕方については他の方の回答のものでいいと思います。

多分質問の答えではないので誰も指摘していないと思うのですが、

$ymd = isset($_GET['ymd']) ? $_GET['ymd'] : date("Y-m-d");
$query = $mysqli->query(" SELECT * FROM tasks WHERE task_date = '$ymd' ");

の部分はユーザーがGETのパラメータを書き換えることによって、本来想定されていないSQLが実行できてしまうので危険です。

ここでのチェックには checkdate関数を使うといいと思います。
練習課題ですので、実際に値を整形して、checkdateをかけるまでの処理は記載しないでおきます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/10 12:46

    いつもご回答ありがとうございます。

    ご指摘ありがとうございます。パラメータのや表示や引き継ぎに関して未だ知識が乏しいので、再度確認しておきます。
    表示がされてみた後に、checkdate関数を用い、パラメータの危険性に対し対策を考えてみます。

    キャンセル

0

私だったらという回答をします。
<table border="1">
    <thead>
    <tr>
        <th>タイトル</th>
        <th>日時</th>
        <th>場所</th>
        <th>メモ</th>
    </tr>
    </thead>
    <tbody>
    <?php
        foreach($taskData as $data){
            echo '<tr>';
            echo '<td>'.$data['title'].'</td><td>'.$data['task_date'].'</td><td>'.$data['place'].'</td><td>'.$data['memo'].'</td>';
            echo '</tr>';
        }
    ?>
    </tbody>
</table>
といった具合に直接echoさせて表示させるようにしてみてはいかがでしょうか。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/07/10 11:00

    -1 した者ではありませんが、ちょっと PHP っぽくないのと XSS 脆弱性があると思います

    キャンセル

  • 2015/07/10 11:08 編集

    > XSS 脆弱性があると思います

    そのとおりですね。ただ今回はものすごく単純に考えただけ(ただ表示させただけ)なので、参考程度にしてもらえればなーと思います。
    本当に何も考えてなかったので。

    >ちょっと PHP っぽくない

    まあ、私は完全に独学なので、正直何がPHPっぽいかはわかってません。
    PHPっぽくなくても実現できてしまいますし・・・

    キャンセル

  • 2015/07/10 12:22

    ご回答ありがとうございます。
    まだまだ練習の身なので、脆弱性に関しては未だ視野に入れていない為、詳しい内容に関しては私としても判断できないですが、非常に参考になりました。ありがとうございました。

    キャンセル

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

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

関連した質問

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