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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

3317閲覧

データベースから複数レコードを取得し、その複数レコードから条件にあった値を取得して変数に格納したい

cambodia

総合スコア12

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2021/01/27 04:44

編集2021/01/27 11:51

#データベースから複数レコードを取得し、その複数レコードから条件にあった値を取得して変数に格納したい
初めまして。
php初心者です。
クイズのウェブサイトを作っています。

10問あるクイズの内、8問正解すると、
以下のテーブルにデータがINSERTされるようにしています。
イメージ説明
※user_idは、ユーザー名。ユーザーによって変わります。
※subject_idは、クイズの種類。クイズの種類によって1から100まであります。
※starは、8問正解を何回達成したかを示す数値です。
1から3まであって、最終的に
1は、「1回クリア!」
2は、「2回クリア!」
3は、「3回クリア!」
と表示させる予定です。


このstarカラムの数値を、変数$starに格納して、result.phpの中で表示させたいと考えています。
result.phpは、クイズの種類ごとに分けており、以下のように記述しています。
コメントに番号をふっています。
私としては、コメント番号の④と⑤がダメだと思っています。
しかし、やり方がわからず、以下のような記述でストップしています。

result.php

php

1 2<?php 3session_start(); 4$user_id = $_SESSION['user_id']; 5 6$star1 =""; 7$star2 =""; 8$star3 =""; 910<省略> 1112$star100 =""; 13 14 15//①user_idを条件にして starテーブルを読み込む 16//②指定したユーザーのレコードを複数取得する 17 18require_once('config.php'); 19$dsn = 'mysql:host=' . $config['host'] . '; dbname=' . $config['database'] . '; charset=utf8'; 20$user = $config['user']; 21$password = $config['password']; 22 23try{ 24 $dbh = new PDO($dsn, $user, $password); 25 $sql = " SELECT * FROM star WHERE user_id = :user_id"; 26 $stmt = $dbh->prepare($sql); 27 $stmt->bindValue(':user_id', $user_id); 28 $stmt->execute(); 29 $data = $stmt->fetchAll(); //③fetchAllで複数レコードの値を全て取得する 30 31 if($data['subject_id'] == 1){ //④もし、subject_idが1なら、 32 $star1 = $data['star']; //⑤そのレコードのstarカラムの値を$star1に格納する 33 34  }else if($data['subject_id'] == 2){ 35 $star2 = $data['star']; 36 37  }else if($data['subject_id'] == 3){ 38 $star3 = $data['star']; 39 } 40 4142 <省略> 4344 45  }else if($data['subject_id'] == 100){ 46 $star100 = $data['star']; 47 } 48 49 }catch(PDOException $e){ 50 echo $e->getMessage(); 51 exit; 52 } 53 54?> 55 56 57<!DOCTYPE html> 58<html lang="ja"> 59<head> 60 <meta charset="UTF-8"> 61 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 62 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 63 <title>サンプル</title> 64 65 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> 66 67</head> 68<body> 69 70 <table> 71 72 <tr> 73 <td> 74 <small>クイズ1</small> 75 </td> 76 <td> 77 <?php echo $star; ?> 78 </td> 79 </tr> 80 81 <tr> 82 <td> 83 <small>クイズ2</small> 84 </td> 85 <td> 86 <?php echo $star; ?> 87 </td> 88 </tr> 89 90 <tr> 91 <td> 92 <small>クイズ3</small> 93 </td> 94 <td> 95 <?php echo $star; ?> 96 </td> 97 </tr> 98 99     ↓ 100    <省略> 101     ↓ 102 103 <tr> 104 <td> 105 <small>クイズ100</small> 106 </td> 107 <td> 108 <?php echo $star100; ?> 109 </td> 110 </tr> 111 112 113 </table> 114</body> 115</html> 116 117

#ご指導、よろしくお願いいたします

foreachやら、fetchAllの使い方をよく理解しておりません。
わかっているのは、
fetchは、SELECT文で取得したデータの一番上のレコードを取得する
fetchAllは、SELECT文で取得したデータをすべて取得する

foreachは、データを配列にして繰り返し処理をする。

という感じです。

私の記述では、fetchAllでデータベースのレコードを取得して、配列の状態になっていると理解しています。
そこから、if文の条件(今回では、subject_idの条件)にあったレコードのstarカラムの値を変数に格納するところでつまづいていると考えています。

どうぞよろしくお願いいたします。

#[追記]アドバイスを元にやってみた結果

tryの処理を以下の記述でやってみますと、

2131646

という表示を取得できました。
これは、subject_idカラムの値が4レコード分連なったものです。

1レコード目 2
2レコード目 13
3レコード目 16
4レコード目 46

このsubject_idカラムの値と同じレコードにあるstarカラムの値を変数に格納したいです。

例えば、
1レコード目であれば、$star2という変数に、starカラムの値である 3 を代入する
2レコード目であれば、$star13という変数に、starカラムの値である 1 を代入する
3レコード目であれば、$star16という変数に、starカラムの値である 1 を代入する
4レコード目であれば、$star46という変数に、starカラムの値である 1 を代入する

このやり方がさっぱりわかりません。

php

1//starテーブルを読み込んで、 2try{ 3 $dbh = new PDO($dsn, $user, $password); 4 $sql = " SELECT * FROM star WHERE user_id = :user_id"; 5 $stmt = $dbh->prepare($sql); 6 $stmt->bindValue(':user_id', $user_id); 7 $res = $stmt->execute(); 8 $list = $stmt->fetchAll(); 9 10 foreach($list as $data){ 11 12 for ($i = 1; $i <= 50; $i++){ 13 if($i == $data['subject_id']){ 14 echo $i; 15 } 16 } 17 18 } 19 20}catch(PDOException $e){ 21 echo $e->getMessage(); 22 exit; 23}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

fetchAllでデータベースのレコードを取得して、配列の状態になっていると理解しています。

var_dump()を覚えてください。
どのような形でデータ入っているのか可視化できます。

php

1$data = $stmt->fetchAll(); 2var_dump($data); 3

「どのように処理をするか」はこの結果を見てからでもいいです。
配列の階層を掘り下げていくのは慣れるしかないです。できればもっと簡単なコードで。

あとはいちいち全て変数に入れずとも、
forで100回ループしてsubject_idと一致するときだけ「〇回クリア」と出すとか、ちょっと悪手ですが、subject_idごとに100回SELECT投げて結果によって出力を変えても良いと思います。

やろうと思えば、SQLでLOOPしてPHPでロジックかまさずとも「出力したいデータの形」を作って、PHPは出力だけに集中させることもできると思います(予定を登録するカレンダーでやったことがある。)。

投稿2021/01/27 05:35

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cambodia

2021/01/27 08:20

m.ts10806さん ご指導ありがとうございます。 var_dumpしてみました。 array(4) { [0]=> array(8) { ["id"]=> string(1) "1" [0]=> string(1) "1" ["user_id"]=> string(3) "ume" [1]=> string(3) "ume" ["subject_id"]=> string(1) "2" [2]=> string(1) "2" ["star"]=> string(1) "3" [3]=> string(1) "3" } [1]=> array(8) { ["id"]=> string(1) "2" [0]=> string(1) "2" ["user_id"]=> string(3) "ume" [1]=> string(3) "ume" ["subject_id"]=> string(2) "13" [2]=> string(2) "13" ["star"]=> string(1) "1" [3]=> string(1) "1" } [2]=> array(8) { ["id"]=> string(1) "3" [0]=> string(1) "3" ["user_id"]=> string(3) "ume" [1]=> string(3) "ume" ["subject_id"]=> string(2) "16" [2]=> string(2) "16" ["star"]=> string(1) "1" [3]=> string(1) "1" } [3]=> array(8) { ["id"]=> string(1) "4" [0]=> string(1) "4" ["user_id"]=> string(3) "ume" [1]=> string(3) "ume" ["subject_id"]=> string(2) "46" [2]=> string(2) "46" ["star"]=> string(1) "1" [3]=> string(1) "1" } }
cambodia

2021/01/27 08:25

forで100回ループしてsubject_idと一致するときだけ「〇回クリア」と出す ↓ このやり方が、私の頭ではなかなかイメージできなくて(泣く)
m.ts10806

2021/01/27 08:30

最悪、100回ループの中でfetchAllで取得したデータを全回ししてもいいですよ。とりあえずそれでも。 100×データ数 にはなりますが、「とりあえずできるやり方」です。
cambodia

2021/01/27 10:48

ご連絡ありがとうございます。
cambodia

2021/01/27 11:52

アドバイスを元に質問に追記しました。
guest

0

ベストアンサー

$star1, $star2, $star3, ... が不毛って思うのなら、
配列で管理すればいいじゃない。
$star[1]とかって。
それなら、

<?php for ($i = 1; $i <= 100; $i++) : ?> <tr> <td> <small>クイズ<?=$i?></small> </td> <td> <?php echo $star[$i]; ?> </td> </tr> <?php endfor; ?>

で100個出力できるし。

fetchAll()したら$data[0]に1件目のレコードが、$data[1]には2件目が、
と[n]のnを変化させればアクセスできるわけで、
$data[1]['star']などとすれば、2件目のレコードのstarが得られるかと。

投稿2021/01/27 05:11

編集2021/01/28 00:03
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cambodia

2021/01/27 10:00

m6uさん ご指導ありがとうございます。 参考にさせていただきます。 for文で、$iに1から100までの数字を順番に当て込まれるようにする、という処理ですかね。 for文をほとんど使ったことがないので、勉強になります。 ちなみに、 質問の中で記述したコードの try{ $dbh = new PDO($dsn, $user, $password); $sql = " SELECT * FROM star WHERE user_id = :user_id"; $stmt = $dbh->prepare($sql); $stmt->bindValue(':user_id', $user_id); $stmt->execute(); $data = $stmt->fetchAll(); ですが、ここには、カラムでいうと、id, user_id, subject_id, starの4つのカラムの値が、 4レコード分$dataに配列として格納されているんですよね? その場合、subject_idカラムの4レコードの値(今回ですと、2,13,16,46になります)を、echoする場合、どのような記述ができますでしょうか? おそらくかなり初歩的なことだと思うのですが、それがわからなくて。
cambodia

2021/01/27 11:52

アドバイスを元に質問に追記しました。
退会済みユーザー

退会済みユーザー

2021/01/28 00:02

var_dump()やprint_r()を使って$dataの中身をチェックしたほうが絶対早いし理解できると思うのでやっていただきたいです。 fetchAll()したら$data[0]に1件目のレコードが、$data[1]には2件目が、と[n]のnを変化させればアクセスできるわけで、 $data[1]['star']などとすれば、2件目のレコードのstarが得られるかと。
cambodia

2021/01/28 00:05

ありがとうございます! やってみます! var_dump 使ってなかったのでこれから使うようにします!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問