🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

1回答

1190閲覧

todo項目を管理するカレンダーの謎動作

larachalle

総合スコア11

PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2021/01/06 06:37

php

1<?php 2 3namespace MyApp; 4 5require_once('config.php'); 6require_once('functions.php'); 7 8class Calendar { 9 public $prev; 10 public $next; 11 public $yearMonth; 12 public $month; 13 private $_thisMonth; 14 private $_dbh; 15 private $_myname; 16 17 public function __construct() { 18 try { 19 if (!isset($_GET['t']) || !preg_match('/\A\d{4}-\d{2}\z/', $_GET['t'])) { 20 throw new \Exception(); 21 } 22 $this->_thisMonth = new \DateTime($_GET['t']); 23 } catch (\Exception $e) { 24 $this->_thisMonth = new \DateTime('first day of this month'); 25 } 26 $this->prev = $this->_prevLink(); 27 $this->next = $this->_nextLink(); 28 $this->month = $this->_thisMonth->format('m'); 29 $this->yearMonth = $this->_thisMonth->format('F Y'); 30 $this->_dbh = connectDb(); 31 $this->_myname = myname(); 32 } 33 34 // 前月へのリンク 35 private function _prevLink() { 36 $dt = clone $this->_thisMonth; 37 return $dt->modify('-1 month')->format('Y-m'); 38 } 39 40 41 // 翌月へのリンク 42 private function _nextLink() { 43 $dt = clone $this->_thisMonth; 44 return $dt->modify('+1 month')->format('Y-m'); 45 } 46 47 // ログイン中のユーザーに関するテーブル作成 48 public function user($myname){ 49 $sql = "create table if not exists {$myname}(id int not null auto_increment, 50 time text, 51 seq int not null, 52 type enum('notyet', 'done', 'deleted') default 'notyet', 53 title text, 54 created datetime, 55 modified datetime, 56 KEY type(type), 57 KEY seq(seq), 58 primary key(id))"; 59 $stmt = $this->_dbh->prepare($sql); 60 $stmt->execute(); 61 } 62 63 // todoリスト 64 private function _todoList($time){ 65 $sql = "select * from {$this->_myname} where time = '{$time}' and type != 'deleted' order by seq"; 66 $stmt=$this->_dbh->prepare($sql); 67 $stmt->execute(); 68 $tasks = $stmt->fetchAll(); 69 $time = str_replace('-', '_', $time); 70 if(count($tasks)==0){ 71 $content = "<ul id='{$time}'></ul>"; 72 return $content; 73 } 74 75 $i = 0; 76 foreach ($tasks as $task){ 77 $x = h($task['id']); 78 $y = h($task['type']); 79 $z = $y=='done' ? 'checked':''; 80 $q = $y=='notyet' ?'editTask':''; 81 $r = h($task['title']); 82 global $i; 83 $i++; 84 $content .= "<li id='task_{$x}' data-id='{$x}'> 85 <input type='checkbox' class='checkTask' {$z}> 86 <span class='{$y}'>$r</span> 87 <span class='{$q}'>[編集]</span> 88 <span class='deleteTask'>[削除]</span> 89 <span class='drag'>[drag]</span> 90 </li>"; 91 if($i==count($tasks)){ 92 $content = "<ul id='{$time}'>{$content}</ul>"; 93 return $content; 94 } 95 } 96 } 97 98 // カレンダー表示 99 public function show() { 100 $tail = $this->_tail(); 101 $body = $this->_body(); 102 $head = $this->_head(); 103 $html = '<tr>' . $tail . $body . $head . '</tr>'; 104 echo $html; 105 } 106 107 // 前月の末日以前数日 108 private function _tail() { 109 $tail = ''; 110 $lastDayOfPrevMonth = new \DateTime('last day of ' . $this->yearMonth . ' -1 month'); 111 while ($lastDayOfPrevMonth->format('w') < 6) { 112 $x=$this->_todoList($lastDayOfPrevMonth->format( "Y-m-d")); 113 $y=$lastDayOfPrevMonth->format( "Y-m-d"); 114 $tail = sprintf('<td id="'.$y.'" class="gray" valign="top"><span>%d</span><br>'.$x.' 115 </td>', $lastDayOfPrevMonth->format('d')) . $tail; 116 $lastDayOfPrevMonth->sub(new \DateInterval('P1D')); 117 } 118 return $tail; 119 } 120 121 // 当月の日にち 122 private function _body() { 123 $body = ''; 124 $period = new \DatePeriod( 125 new \DateTime('first day of ' . $this->yearMonth), 126 new \DateInterval('P1D'), 127 new \DateTime('first day of ' . $this->yearMonth . ' +1 month') 128 ); 129 $today = new \DateTime('today'); 130 foreach ($period as $day) { 131 if ($day->format('w') === '0') { $body .= '</tr><tr>'; } 132 $todayClass = ($day->format('Y_m_d') === $today->format('Y_m_d')) ? 'today' : ''; 133 $x=$this->_todoList($day->format('Y-m-d')); 134 $y=$day->format('Y-m-d'); 135 $body .= sprintf('<td id="'.$y.'" valign="top"><span class="youbi_%d %s"><span>%d</span></span><br>' 136 .$x.'</td>', $day->format('w'), $todayClass, $day->format('d')); 137 } 138 return $body; 139 } 140 141 // 翌月の初日以降数日 142 private function _head() { 143 $head = ''; 144 $firstDayOfNextMonth = new \DateTime('first day of ' . $this->yearMonth . ' +1 month'); 145 while ($firstDayOfNextMonth->format('w') > 0) { 146 $x=$this->_todoList($firstDayOfNextMonth->format('Y-m-d')); 147 $y=$firstDayOfNextMonth->format('Y-m-d'); 148 $head .= sprintf('<td id="'.$y.'" class="gray" valign="top"><span>%d</span><br>'.$x.'</td>', $firstDayOfNextMonth->format('d')); 149 $firstDayOfNextMonth->add(new \DateInterval('P1D')); 150 } 151 return $head; 152 } 153 154}

todo項目を管理するカレンダーを作成しているのですが、謎な動作をします。

<?php $cal->show(); ?>

でカレンダー表示すると
一部のtodo項目、
"<li id='task_{$x}' data-id='{$x}'>
<input type='checkbox' class='checkTask' {$z}>
<span class='{$y}'>$r</span>
<span class='{$q}'>[編集]</span>
<span class='deleteTask'>[削除]</span>
<span class='drag'>[drag]</span>
</li>"
が抜け落ちたり、そもそも _todoList($time)関数において、 return $content;
がされない場合すらあります。
例えば、12月のカレンダーのおける12/27日のtodo項目はデータベースから全てひっぱてこれているにもかかわらず,1月のカレンダーのおける12/27日のtodo項目はデータベースから一部しかひっぱてこれないといった動作が起こります。

このような動作をするのはなぜなんでしょうか?
コードにおかしなところがもしあるようでしたらご指摘下さい。

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

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

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

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

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

m.ts10806

2021/01/06 08:41

過去質問ほとんど解決済みにされないまま、 何かしらコメントや回答があってもほぼ無反応のまま通されてますが、 それらをきちんと解決するのが先ではないでしょうか。 「解決する気ない」として、余計に誰もアドバイスしなくなります。(現状既にそうなってるように見える)
退会済みユーザー

退会済みユーザー

2021/01/06 10:30

global $i;って必要? クラスの外で$iループカウンター使って上書きしてたりしたら嘲笑う
larachalle

2021/01/06 12:51

今まで質問した分はすべて自分で解決しました。解決済みに修正しておきます。 クラスの外で$iループカウンター使ってはいません。
guest

回答1

0

ベストアンサー

private function _todoList($time){
のところの
foreach ($tasks as $task){
ループの中で
global $i;
としているため、
クラスの呼び元で何らかのループカウンターとしてグローバル変数の$iを使っていると
(意図せず?意図的に?)その数値を使って処理してしまい、
そりゃぁゼロから始まらない可能性があるよなぁとしか言えません。

foreach ($tasks as $task){
ループの外で$i = 0;として初期化しているように見えますが、
private function _todoList($time){
スコープ内のローカル変数$iじゃなく、グローバル変数の$iを参照していることに気づいてください。

PHP: 変数のスコープ - Manual

投稿2021/01/06 10:53

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

larachalle

2021/01/06 16:37

ありがとうございます。 うまく動作しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問