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

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

ただいまの
回答率

90.75%

  • PHP

    19204questions

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

PHPのforeach文について

解決済

回答 1

投稿 編集

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

mashumaro0628

score 12

前提・実現したいこと

echo $course_name_array[2];
の下のforeach文を正常に動作させたいです

発生している問題・エラーメッセージ

Notice: Undefined variable: key1 in C:\xampp\htdocs\training\aaa\index.php on line 19

Fatal error: Call to a member function prepare() on null in C:\xampp\htdocs\training\aaa\index.php on line 19

該当のソースコード

$size_array=array();
    $course_name="";
    $course_name_array=array();
    $col_math=0;
    $pdo = new PDO("mysql:host=localhost;dbname=doubutsu;charset=utf8",'root','admin');

    //コース名抽出
    try{
        $stmt = $pdo -> prepare("SELECT course_name from Course");
        $stmt->execute();
        foreach($stmt as $key) {
              $course_name.="<td>".$key['course_name']."</td>";
              $course_name_array[]=$key['course_name'];    
          }
        echo $course_name_array[2];
        foreach ($course_name_array as $key1 ) {
            $stmt = $pdo -> prepare("SELECT Size from Size where course_name='".$key1."'");
            $stmt->execute();
            foreach ($stmt as $key2) {
                $size_array=$key2['Size'];
            }
            $pdo = null;
        }
    }catch(PDOException $e){
         exit('データベース接続失敗' . $e->getMessage());
    }    

試したこと

echo $course_name_array[2]までは値がとれています

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

create table Course (
Course_Number int(5) auto_increment,
Course_Name varchar(30) not null,
Release_Range boolean not null,
Maintenance date not null,
primary key(Course_Number));

insert into Course(Course_Name,Release_Range,Maintenance) values('グルーミング',true,'20171112');
insert into Course(Course_Name,Release_Range,Maintenance) values('トリミング',true,'20171112');

insert into Course(Course_Name,Release_Range,Maintenance) values('シャンプー',true,'20171112');

create table Size (
Size_Number int(5) auto_increment,
Size_name varchar(20) not null,
Release_Range boolean not null,
Maintenance date not null,
primary key(Size_Number)
);

insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('小型',true,20171112,'グルーミング');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('中型',true,20171112,'グルーミング');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('大型',true,20171112,'グルーミング');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('小型',true,20171112,'トリミング');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('中型',true,20171112,'トリミング');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('大型',true,20171112,'トリミング');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('小型',true,20171112,'シャンプー');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('中型',true,20171112,'シャンプー');
insert into Size(Size_name,Release_Range,Maintenance,Course_name) values('大型',true,20171112,'シャンプー');

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

ステートメントはfetchしないのでしょうか?

$course_name="";
$course_name_array=[];

$stmt = $pdo -> query("SELECT course_name from Course");
$rows=$stmt->fetchAll(PDO::FETCH_ASSOC);

foreach($rows as $row) {
  $course_name.="<td>".$row['course_name']."</td>";
  $course_name_array[]=$row['course_name'];    
}

 追記

改めて見てみましたが、Courseテーブルからcourse_nameをすべて抜き出してそれに合致する
sizeを拾っているんですよね?
であればsql文は1回発行すればよくないですか?
ただしcourse_nameがどちらかのテーブルでユニークでない場合はm×nのデータが抽出されちゃいますけどね

try{
  $sql ="select t1.course_name,t2.Size from Course as t1 ";
  $sql.="inner join Size as t2 on t1.course_name=t2.course_name ";
  $stmt = $pdo -> query();
  $stmt->execute();
  $rows=$stmt->fetchAll(PDO::FETCH_ASSOC);
  foreach($rows as $row) {
    $course_name.="<td>".$row['course_name']."</td>";
    $course_name_array[]=$row['course_name'];
    $size_array=$row['Size'];
  }
}catch(PDOException $e){
  exit('データベース接続失敗' . $e->getMessage());
}

 db結合

select t1.course_name,t2.size_name from Course as t1 
inner join Size as t2 on t1.course_name=t2.course_name 


とすれば、以下が得られますね

course_name size_name
グルーミング 小型
グルーミング 中型
グルーミング 大型
トリミング 小型
トリミング 中型
トリミング 大型
シャンプー 小型
シャンプー 中型
シャンプー 大型

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/01/23 19:59

    その部分はfetchなしで動きました。
    しっかり配列$course_name_arrayに文字化けなしの値が入ってるのにも関わらず
    下のforeachでは値が配列に入っていない挙動になっています。

    キャンセル

  • 2018/01/23 20:13

    その後ろは全体的な構造がおかしいです
    foreach ($course_name_array as $key1) でループ回してる中で
    $pdo = new PDO("mysql:host=localhost;dbname=doubutsu;charset=utf8",'root','admin');
    するのはあたらしいセッションをループしているだけガンガン開いているんですよね?
    $pdoは先頭の方で宣言して、使いまわしたほうがよいでしょう

    またqueryを実行していますが、prepareで処理して下さい

    キャンセル

  • 2018/01/23 20:32

    > $pdoは先頭の方で宣言して、使いまわしたほうがよいでしょう
    prepare もぜひ!w

    キャンセル

  • 2018/01/23 20:44

    変えてみたんですがこれでいいですか?
    さっきとあまり状況は変わらないみたいで
    $course_name_arrayの値は依然としてちゃんと入ってるみたいです

    キャンセル

  • 2018/01/23 20:55

    質問者さんもしくは回答者の私が何か大きく勘違いしているかもしれません。
    追記のところのロジックを再考してみて下さい

    キャンセル

  • 2018/01/23 21:07

    この後値を表にして使うために両方の値が必要でm×nが必要なんですよね。
    種類1 種類2  種類3
    大中小 大中小 特大中小
    みたいな感じで使います。

    キャンセル

  • 2018/01/23 21:11

    PHPのプログラムの問題というよりはmysqlのDB設計の問題のような気がします。
    テーブルのサンプルを挙げてもらったほうがよいかもしれません
    (もしサンプルを上げる場合は元の質問に追記する形でつけてください)

    キャンセル

  • 2018/01/23 21:20

    DBのテーブルですか、htmlのテーブルサンプルですか

    キャンセル

  • 2018/01/23 21:34

    create table Course(id int unique,course_name varchar(20));
    insert into Course valuse(1,'aaa'),(2,'bbb')・・・;
    create table Size (id int unique,course_name varchar(20),Size int);
    insert into Course valuse(1,'aaa',100),(2,'aaa',150),(3,'bbb',200),・・・;

    のようなデータのかぶり方がわかるようなSQL文で書くとわかりやすいです

    キャンセル

  • 2018/01/23 21:55

    わかりにくくて申し訳ないです

    キャンセル

  • 2018/01/23 21:55

    修正しました

    キャンセル

  • 2018/01/23 22:02

    SizeテーブルにCourse_nameカラムが見当たりませんが

    キャンセル

  • 2018/01/23 22:03

    すみません、諸事情で後からalter table addでカラム追加しました

    キャンセル

  • 2018/01/23 22:08

    なるほどalter table addをしたとして

    「SELECT Size from Size」とありますがSizeというカラムがないですね
    Size_NumberかSize_nameのどちらかを参照するのでは?

    キャンセル

  • 2018/01/23 22:23

    そうでした。
    打ち間違えでsize_numberを参照してます。

    キャンセル

  • 2018/01/23 22:23

    すみません、nameの方です。
    あと遅くまで付き合っていただいてありがとうございます。

    キャンセル

  • 2018/01/23 22:30

    dbの結合と結果を表記しておきました
    得られるものはこれで問題ないのでは?

    キャンセル

  • 2018/01/23 22:38

    ありがとうございます!
    あとは横ではなく縦に結合させて同じ内容のセルを結合したいんですが流石に贅沢ですかね。

    キャンセル

  • 2018/01/24 11:13

    > 縦に結合させて同じ内容のセルを結合したい

    ちょっと状況がわかりません。
    仕様をつめたら別の機会にまた質問をなげてみてください

    キャンセル

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

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

関連した質問

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

  • PHP

    19204questions

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