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

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

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

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

Q&A

3回答

860閲覧

祝日名を正確に表示する方法

KaenTei

総合スコア8

PHP

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

0グッド

0クリップ

投稿2019/09/10 00:14

php初心者です。
最近はカレンダーを作っていますが、なかなか祝日名は正確に表示しません。試しますので、自分でholiday.csvファイルを作りました。
内容はこんな感じです。
2019-01-01,元日
2019-01-14,成人の日
2019-02-11,建国記念の日
2019-03-21,春分の日
2019-04-29,昭和の日
2019-04-30,休日
2019-05-01,休日
2019-05-02,休日
2019-05-03,憲法記念日
2019-05-04,みどりの日
2019-05-05,こどもの日
2019-05-06,休日
2019-07-15,海の日
2019-08-11,山の日
2019-08-12,休日
2019-09-16,敬老の日
2019-09-23,秋分の日
2019-10-14,体育の日
2019-10-22,休日
2019-11-03,文化の日
2019-11-04,休日
2019-11-23,勤労感謝の日

php

1<?php 2ini_set('display_errors', 1 ); 3ini_set('error_reporting', E_ALL); 4 5// タイムゾーンを設定 6date_default_timezone_set('Asia/Tokyo'); 7 8//1ケタの前に0をつける 9function output($a){ 10 if(ctype_digit(strval($a)) && 0 < $a && $a < 10 ){ 11 return "0".$a; 12 }else{ 13 return $a; 14 } 15} 16 17function loadHolidays() { 18//祝祭日データ CSV 方法2 19$file = file_get_contents('./holiday.csv'); 20$data = $file; 21// 行ごとに分割 22 $lines = explode("\n", $data); 23 $line = ''; 24 foreach ($lines as $line) { 25// カンマで分割 26 $cols = explode(",", $line); 27 $holidays[] = [ trim($cols[0]), trim($cols[1]) ]; 28 } 29// 現在から3年間分の年末年始を追加 30 $currentYear = intval(date('Y')); 31 for ($i = 0; $i < 1; $i++) { // 3年間 32 $y = $currentYear + $i; 33 $date = strtotime("$y-12-29"); // 12月29日から 34 for ($j = 0; $j < 6; $j++) { // 1月3日まで6日間 35 $dateStr = date('Y-m-d', $date); 36 $holidays[] = [ $dateStr, '年末年始' ]; 37 $date = strtotime("+1 day", $date); 38 } 39 } 40 return $holidays; 41} 42 43// 前月・次月リンクが押された場合は、GETパラメーターから年月を取得 44if (isset($_GET['ym'])) { 45 $ym = new DateTime ($_GET['ym']); 46 $ym -> format('Y-m'); 47 $nm = new DateTime($_GET['ym']); 48 $nm -> format('Y-m'); 49 $firstday = new DateTime ($_GET['ym']); 50 $firstday -> format('Y-m-01'); 51} else { 52 // 今月の年月を表示 53 $ym = new DateTime('now'); 54 $ym -> format('Y-m'); 55 $nm = new DateTime('now'); 56 $nm -> format('Y-m'); 57 $firstday = new DateTime('first day of this month'); 58 $firstday -> format('Y-m-d'); 59} 60 61// 今日の日付 62$today = new DateTime('now'); 63$today =$today -> format('Y-m-d'); 64 65// カレンダーのタイトルを作成 66$html_title = $ym -> format('Y年n月'); 67 68// 該当月の日数を取得 69$day_count = $ym -> format('t'); 70 71// 1日が何曜日か 0:日 1:月 2:火 ... 6:土 72$youbi = $firstday -> format('w'); 73 74// カレンダー作成の準備 75$weeks = []; 76$week = ''; 77 78// 第1週目:空のセルを追加 79// 例)1日が水曜日だった場合、日曜日から火曜日の3つ分の空セルを追加する 80$week .= str_repeat('<td></td>', $youbi); 81 82//祝日の関数を呼び出す 83 84$holidays = loadHolidays(); 85 86$holidaylist = array_column($holidays,0); 87$holidaynamelist = array_column($holidays,1); 88$a = array_flip($holidaylist); 89$b = array_flip($holidaynamelist); 90$c = array_combine($holidaylist,$holidaynamelist); 91var_dump($c); 92$d = array_flip($c); 93 94for ( $day = 1; $day <= $day_count; $day++, $youbi++) { 95 $dayday = output($day); 96 97 // 20XX-XX-X 98 $yearmonth=$ym -> format('Y-m'); 99 $date = $yearmonth . '-' . $dayday; 100 101 $holidayCheck = in_array($date,$holidaylist); 102 $holidayNamecheck = in_array($date,$d); 103 104 if ($today == $date) { 105 $week .='<td class = "today">' . $dayday; 106 } else if ($holidayCheck === true && $holidayNamecheck === true) { 107 $week .='<td class="rest">' . $dayday . implode($holidaynamelist); 108 } 109 else { 110 $week .= '<td>' .$dayday; 111 } 112 $week .= '</td>'; 113 114 // 週終わり、または、月終わりの場合 115 if ($youbi % 7 == 6 || $day == $day_count) { 116 117 if ($day == $day_count) { 118 // 月の最終日の場合、空セルを追加 119 // 例)最終日が木曜日の場合、金・土曜日の空セルを追加 120 $week .= str_repeat('<td></td>', 6 - ($youbi % 7)); 121 } 122 123 // week配列にtrを追加する 124 $weeks[] = '<tr>' . $week . '</tr>'; 125 126 // weekをリセット 127 $week = ''; 128 } 129} 130 131// 前月・次月の年月を取得 132$prev =$ym -> modify('first day of last month'); 133$next =$nm -> modify('first day of next month'); 134 135?> 136<!DOCTYPE HTML> 137<html> 138<head> 139<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 140 141<title>PHPカレンダー</title> 142 143<link rel="stylesheet" type="text/css" href="style.css"> 144</head> 145 146<body> 147 <div class="container"> 148 <h3><a href="./?ym=<?php echo $prev ->format('Y-m'); ?>"><input type="submit" value="<" class="btn"></a> <?php echo $html_title; ?> <a href="./?ym=<?php echo $next ->format('Y-m'); ?>"><input type="submit" value=">" class="btn"></a></h3> 149 <table class="table-table-bordered"> 150 <tr> 151 <th></th> 152 <th></th> 153 <th></th> 154 <th></th> 155 <th></th> 156 <th></th> 157 <th></th> 158 </tr> 159 <?php 160 foreach ($weeks as $week) { 161 echo $week; 162 } 163 ?> 164 </table> 165 </div> 166</body> 167</html>

今まで表示されるものはこんな感じです。
イメージ説明

よろしくお願いいたします。

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

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

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

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

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

y_waiwai

2019/09/10 00:56

で、しつもんはなんでしょうか
guest

回答3

0

なにがしたいのやら、このコード。

$holidaylist = array_column($holidays,0); $holidaynamelist = array_column($holidays,1); $a = array_flip($holidaylist); $b = array_flip($holidaynamelist); $c = array_combine($holidaylist,$holidaynamelist); var_dump($c); $d = array_flip($c);

と思ったらあとででてくるこの場面。

$dayday = output($day); // 20XX-XX-X $yearmonth=$ym -> format('Y-m'); $date = $yearmonth . '-' . $dayday; $holidayCheck = in_array($date,$holidaylist); $holidayNamecheck = in_array($date,$d);

日付→祝日名は、一つの日付に一つしか祝日名がついていないけど、
祝日名から日付を出すのはダメな構造を自分で作っていることに気づいているかな。
「休日」のなんと多いこと。これを考慮してあるのだろうかと。

でも、そんなことはまだ序の口。
根本的にココがまずい

$week .='<td class="rest">' . $dayday . implode($holidaynamelist);

$holidaynamelistって、

$holidaylist = array_column($holidays,0);

なんだよね。ここで?なぜ全部連結したものを出力する?


あくまで机上のコードだけど、こういうのはどうだろうか。

php

1$holiday_name = ''; 2if (isset($holidays[$date])) { 3 // 祝日名がヒット 4 $holiday_name = $holidays[$date]; 5} // ヒットしなければ空文字列のまま 67if ($holiday_name !== '') { 8 // 祝日名がある 910} 11else { 12 // 祝日名がない 1314}

「yyyy-mm-dd」な形式で日付文字列が生成できていれば、
$holidaysで引き当ててカレンダー出力に織り込むだけじゃないかと。
それを各日付ごとに実施すれば良いだけ。


$holidays[]のキーに日付をもとにした文字列「yyyy-mm-dd」が与えられたら祝日名を返すような構造を考えたのであれば、
いっそ関数化してしまえばラクじゃないですかね。
$holidays[]を参照するたびに日付文字列キーが存在するかどうか確認するところを関数としてラッピングすれば。
(下記、あくまで机上のコード。)

php

1function getHoliday($date) { 2 if (isset($holidays[$date])) { 3 return $holidays[$date]; 4 } 5 else { 6 return ''; 7 } 8}

どうせなら、CSVファイルの読み込み部分も含めてclassにすれば、
初期化時点でCSVファイルから読み込んで祝祭日名を保持し、
getメソッドで祝祭日名を得られる、くらいにすると良いよね。

そういうことを、先行者たちは考えて、
japanese-holiday/japanese-holiday
とか
holiday-jp/holiday_jp
とか出来ているわけで。
車輪の再発明をせずともちゃんと動くのがほしいわけで。

投稿2019/09/10 01:26

編集2019/09/10 03:52
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

KaenTei

2019/09/10 01:40

ご回答ありがとうございます。 最初は日付を判別できますが祝日名は判別できないので、どうやたら祝日名を判別できるのかをかんがえて、array_flipを試しました。でもつぎはどうする知らないです。 $daydayはカレンダーの一日から九日まで直前に0をつけますのでです。 確かに$weekここがまずいです。直し方知らないです。
guest

0

初心者がデバッグするには、途中の要所要所に、echoとかvar_dumpを入れるといいです。
どこまでうまくいっているかがわかります。

投稿2019/09/10 01:21

otn

総合スコア84423

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

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

0

何をしたいのか分かりませんが、私は下記を使ってます。

年に一度、年末頃にcomposer updateが必要ですけど。

投稿2019/09/10 00:31

m.ts10806

総合スコア80765

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

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

KaenTei

2019/09/10 00:48

ご回答ありがとうございます。 私はcsvファイルを読み込んで、祝日を作成したいです。
m.ts10806

2019/09/10 00:50

それだと自分で毎年分作らなければならないしコードも冗長になるのでパッケージを使いましょうという提案をしています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問