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

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

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

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

Q&A

解決済

1回答

2574閲覧

foreachの中に配列のデータを1つずつ出力したいです

higa_yomityu

総合スコア41

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

0グッド

1クリップ

投稿2021/02/06 01:18

現在、自主制作にてカレンダーの中にデータを出力するアプリを作っています。

カレンダーをforeachにて回しているのですが、そのカレンダーの日付ごとにデータを一つずつ出力したいです。

php

1<?php 2//カレンダー 3 //現在時刻の設定 4 date_default_timezone_get('Asia/Tokyo'); 5 6 $year=date('Y'); 7 $month=date('m'); 8 9 //月末日を取得 10 $end_month=date('t',strtotime($year.$month.'01')); 11 12 //月初めの曜日を取得 13 $first_week=date('w',strtotime($year.$month.'01')); 14 15 //月末の曜日を取得 16 $last_week=date('w',strtotime($year.$month. 17 $end_month)); 18 19 $calender=[]; 20 $j=0; 21 22 //1日が始まるまでの穴埋め 23 for($i=0; $i<$first_week; $i++){ 24 $calender[$j][]=''; 25 } 26 27 //1日から月末までループ 28 for($i=1;$i<=$end_month;$i++){ 29 //日曜日まで進んだら改行 30 if(isset($calender[$j]) && count($calender[$j]) === 7){ 31 $j++; 32 } 33 $calender[$j][]=$i; 34 } 35 36 //月末曜日までの穴埋め 37 for($i = count($calender[$j]);$i<7;$i++){ 38 $calender[$j][]=''; 39 } 40 41 $aryweek=['日','月','火','水','木','金','土']; 42?>

php

1//出力したいデータカラム 2 //ログイン者のdataカラムを取り出す 3 $datas=$db->prepare('SELECT data FROM post WHERE member_id=:member_id'); 4 5 //バインド 6 $datas->bindParam(':member_id',$mem['member_id'],PDO::PARAM_STR); 7 8 //実行 9 $datas->execute(); 10 $data=$datas->fetchAll(); 11 12 //ログイン者のcreatedカラムを取り出す 13 $createds=$db->prepare('SELECT created FROM post WHERE member_id=:member_id'); 14 15 //バインド 16 $createds->bindParam(':member_id',$mem['member_id'],PDO::PARAM_STR); 17 18 //実行 19 $createds->execute(); 20 $created=$createds->fetchAll();

html

1<!--カレンダー--> 2<table border="5"> 3 <tr> 4 <?php foreach($aryweek as $week){;?> 5 <th> 6 <?php echo $week;?> 7 </th> 8 <?php };?> 9 </tr> 10 11 <!-- カレンダーのマスを成形する--> 12 <?php foreach($calender as $tr){;?> 13 <tr> 14 <?php foreach($tr as $td){;?> 15 16 <?php if($td !=date('j')){;?> 17 <td> 18 <?php 19 //日付出力 20 echo $td 21 ;?> 22 </td> 23 <?php }else{?> 24 <td class="today"> 25    <!--todayに色付け--> 26 </td> 27 <?php };?> 28   <?php };?> 29 </tr> 30 <?php };?> 31 </table>

試したこと

下記コードを//日付出力の箇所で試してみました。
結果は$td一つに対して$dataの全データが出力されている状況です。

for($i=0;$i<=$end_month;$i++){ if($created[$i]['created']==date('Y-m'.'-'.$td)){ echo $data[$i]['data']; } }

###お願いします
今回の質問では、「foreachの中に配列のデータを1つずつ出力したい」ことなのですが
自分で考えて作ったものなので、気になる点やもっと効率のいいコードがあったら教えてほしいです。

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

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

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

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

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

m.ts10806

2021/02/06 01:20

何が問題ですか?
guest

回答1

0

ベストアンサー

データベースからの読み出しの箇所、なぜ2度に分けて読み出しているのか。
これ、一度にできますよね。
それに、もしもデータが当月分だけじゃなく複数の年月に渡った場合に全部のデータを抽出すると邪魔なので、
一ヶ月分のカレンダーを作ろうとしているのであれば、念の為にcreatedを$year$monthで区切ってみるのも加えてみたり。
それに、ORDER BY句がないので、抽出される順序が不定になってるので補ってみたり。

php

1//出力したいデータカラム 2 //ログイン者のdataカラムを取り出す 3 $stmt=$db->prepare('SELECT data, dayofmonth(created)+1 as "day" FROM post WHERE member_id = :member_id and year(created) = :year and month(created) = :month ORDER BY created'); 4 5 //バインド 6 $datas->bindValue(':member_id', $mem['member_id'], PDO::PARAM_STR); 7 $datas->bindValue(':year', $year, PDO::PARAM_INT); 8 $datas->bindValue(':month', $month, PDO::PARAM_INT); 9 10 //実行 11 $datas->execute(); 12 $data = $datas->fetchAll();

これなら、日付の「日」と投稿データをセットで得られますよ。
MySQL前提でDAYOFMONTH()を使いましたが、1日目がゼロではじまるため、+1しています。
MySQL 5.6のマニュアルでは→12.7 日付および時間関数

なお、安直に「year(created) = :year and month(created) = :month」とした箇所は、
いちいち関数による演算を加えると遅くなる傾向にあるため、
より負担なく高速にするためには
当月の初日の文字列と最終日の文字列を用意してBETWEENするのが良いかと。
「created BETWEEN DATE('2021-02-01') AND DATE('2021-02-28')」
になるように
「created BETWEEN DATE(:gessho) AND DATE(:getsumatsu)」
みたいにしてこれもbindValue()で与えればいいわけで。


もう一つ。
構造の話になってくるのですが、
質問者さんは二次元配列(週単位の配列)を組んで実装していますが、
日曜日から週を始めるためには二次元配列を組まなくてもいい方法があります。

日付を管理する配列だけのシンプルさにして、
曜日を判定して土曜日であればtr要素を出力して週を改めるってだけで実現できます。
日付は常に+1方向で増えていくだけなので、単純な一つのfor()ループだけです。
その日付のデータを出力する前や後に、曜日の判定処理を加えるのです。

tr出力

当月1日の曜日ギャップを調整するfor()ループでtd出力

曜日ごとデータ出力for()ループ開始

その日付データを出力(曜日ごとの色替えや今日の色替えなどもここで)

もしも土曜日ならtr出力して週を改める

ループ終了、繰り返し。

末日以降の曜日ギャップを調整するfor()ループでtd出力

忘れずに閉じtr出力して終了

という流れで、組めるはず。
曜日の繰り返しなんてしなくても組めます。

投稿2021/02/06 02:38

編集2021/02/06 05:49
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2021/02/06 02:54

MySQL詳しくないのでデバッグよろしく。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問