nowrapを加えます
<td nowrap>hogehoge</td>
nowrap追加前

nowrap追加後

2~3日、ずっと悩んでました。。
随机应变 ABCD: Always Be Coding and … : хороший
nowrapを加えます
<td nowrap>hogehoge</td>
nowrap追加前

nowrap追加後

2~3日、ずっと悩んでました。。
1.table tdのcssは
td {
write something;
}
2. table td にclassを付けた場合
例
<td class="selected">hoge</td>
cssは、
td.selected {
write something;
}
3.table tdの中にlink(aタグ)のcss
td a{
write something;
}
4.table classを付けたtdの中のlink(aタグ)のcss
<td class="selected"><a href="?param=hoge">foo</a></td>
cssは
td.selected a{
write something;
}
下のキャプチャのように、classをつけているtdの中のaタグのcolorを#fffにできました。

php側
1.DBから取得した予約データで、時間は+=,予約数は++で連想配列をつくる
2.array_multisortで時間の多い順に連想配列をソート
3.jsに値を渡す
$i = 0;
while($result = $stmt->fetch(PDO::FETCH_ASSOC)){
if($year == substr($result['day'], 0, 4) && $month == substr($result['day'], 7, 2)){
$charge = $result['charge'];
$book[$charge]['course'] += $result['course'];
$book[$charge]['count']++;
$total += $result['course'];
$i++;
}
}
foreach($book as $key => $value){
$time[$key]["course"] = $value["course"];
}
array_multisort($time, SORT_DESC, $book);
foreach($book as $key => $value){
$name_list[] = $key;
$time_list[] = $value["course"];
$count_list[] = $value["count"];
}
chart.js
オプションで、左右の軸を指定する
tickのmaxは配列の中の最も大きい数 x N とする
Math.max.apply(null, array)*N
ただし、javascriptの IEEE 754の計算だと、誤差が生じることがある
例 Math.max.apply(null, array)*1.1 = 90.00000000000001(!?)
IEEE 754は、2進法計算だかららしい。※wikipediaを読んだが、何故二進法だと誤差が出るのかは私の頭では理解不能

そのため、 Math.floor(Math.max.apply(null, array)*N) として、小数点以下切り捨て
var name_arr = JSON.parse('<?php echo $name_l; ?>');
var time_arr = JSON.parse('<?php echo $time_l; ?>');
var count_arr = JSON.parse('<?php echo $count_l; ?>');
var ctx = document.getElementById("BarChart");
var BarChart = new Chart(ctx, {
type: 'bar',
data:{
labels:name_arr,
datasets:[{
label:'予約時間',
data: time_arr,
backgroundColor: "rgba(255,136,86,0.8)",
yAxisID: "y-axis-1",
},{
label:'予約数',
data: count_arr,
backgroundColor: "rgba(54,264,235,0.4)",
yAxisID: "y-axis-2",
}]
},
options:{
responsive: true,
scales:{
yAxes:[{
id: "y-axis-1",
type: "linear",
position: "left",
ticks:{
max: Math.floor(Math.max.apply(null, time_arr)*1.1),
min:0,
stepSize: 30
}
},{
id: "y-axis-2",
type: "linear",
position: "right",
ticks:{
max: Math.max.apply(null, count_arr)+1,
min:0,
stepSize: 1
}
}],
}
}
});
結果:今月

翌月

php側
1.今日の年・月を取得する
2.Getパラメーターで先月・翌月の場合は、$monthを変更する
3.今月が1月の場合は前月の年、12月の場合は翌月の年を変更
4.年と月が一致するデータをDBから取得して、名前と営業成績を連想配列にする
5.array_multisortで、成績順にソートする
6.chart.jsにラベルとデータを渡すため、keyとvalueを配列にしてデコードする
$year = date("Y");
$month = date("m");
if(!empty($_GET["m"])){
$month = date("m", strtotime("".$_GET["m"]." month"));
if($_GET["m"] == -1 && $month == 12){
$year= date("Y", strtotime("-1 year"));
}elseif($_GET["m"] == 1 && $month == 1){
$year= date("Y", strtotime("+1 year"));
}
}
$i = 0;
while($result = $stmt->fetch(PDO::FETCH_ASSOC)){
if($year == substr($result['day'], 0, 4) && $month == substr($result['day'], 7, 2)){
$charge = $result['charge'];
$book[$charge] += $result['course'];
$total += $result['course'];
$i++;
}
}
foreach($book as $key => $value){
$time[$value] = $value;
}
array_multisort($time, SORT_DESC, $book);
foreach($book as $key => $value){
$name_list[] = $key;
$time_list[] = $value;
}
$name_l =json_encode($name_list);
$time_l = json_encode($time_list);
js側
普通のchart.js棒グラフ
var name_arr = JSON.parse('<?php echo $name_l; ?>');
var time_arr = JSON.parse('<?php echo $time_l; ?>');
var ctx = document.getElementById("BarChart");
var BarChart = new Chart(ctx, {
type : 'bar',
data: {
labels: name_arr,
datasets:[{
label: "予約時間(分)",
backgroundColor: "rgba(75, 192, 192, 0.4)",
borderColor:"rgba(75, 192, 192, 1)",
data: time_arr
}]
},
options: {
scales: {
yAxes: [{
ticks : {
beginAtZero:true,
}
}]
}
}
});
view側
1. switch文で、今月・先月・翌月を表示を出し分ける(if elseの方が良かったかも。。。)
2. canvasはdiv wrapperで囲ってサイズ調整
<?php
switch($_GET["m"]){
case -1:
echo "先月の総予約数: ".$i."件<br>";
echo "先月の総予約時間: ".$total."分<br>";
break;
case 1:
echo "来月の総予約数: ".$i."件<br>";
echo "来月の総予約時間: ".$total."分<br>";
break;
default:
echo "今月の総予約数: ".$i."件<br>";
echo "今月の総予約時間: ".$total."分<br>";
break;
}
?>
<div class="wrapper">
<canvas id="BarChart"></canvas><br>
<center><a href="?m=-1">先月</a> | <a href="analytics.php">今月</a> | <a href="?m=1">翌月</a></center>
</div>
結果:今月

翌月

あ、getパラメータは、date(“Ym”, strtotime(+-1 month));で良かったですね。。。
HolidayDateTimeを使います。
https://qiita.com/chiyoyo/items/539dc2840a1b70a8e2c3
require_once("holiday.php");
$datetime = new HolidayDateTime('2018-05-03');
echo $datetime->holiday();
すごいっすね。。頭いいっすね。

ifに書き方を変えると、平日・祝日の判定ができます。
require_once("holiday.php");
$date = '2018-04-29';
$datetime = new HolidayDateTime($date);
if($datetime->holiday()){
echo $datetime->holiday();
}else {
echo "平日";
}

応用すると、
$y = substr($today, 0, 4);
$m = substr($today, 7, 2);
$d = substr($today, 12, 2);
$target_day = $y."-".$m."-".$d;
require_once("holiday.php");
$datetime = new HolidayDateTime($target_day);
if($datetime->holiday()){
echo "<b>".$today. "(".$datetime->holiday().") 予約状況</b><hr>";
$holiday = 1;
}else {
echo "<b>".$today. " 予約状況</b><hr>";
$holiday = 0;
}
祝日判定をして、祝日の場合は予約できないようにします。

<?php elseif($validation == 4): ?> <h1>ご予約内容の確認</h1> <p>ご希望いただいた<?php echo $day; ?>は、<?php echo $holiday; ?>でお休みの為、ご予約できません。<br> 前のページに戻り、異なる日程にてご入力くださいませ。</p> <hr> <b>お名前</b><br> <?php echo $name; ?>様<br> <b>メールアドレス</b><br> <?php echo $mail; ?><br> <b>ご予約日付</b><br> <?php echo $day; ?><br> <b>時間</b><br> <?php echo $stime; ?>~<?php echo $etime; ?><br> <b>コース</b><br> <?php echo $course; ?>分<br> <b>担当</b><br> <?php echo $charge; ?><br><br> <input type="button" value="内容を修正する" onclick="history.back(-1)"> </form>
うわー

git hubからdownloadします。
https://github.com/dapphp/securimage
git clone https://github.com/dapphp/securimage.git
早速使ってみます。
<img id="captcha" src="securimage/securimage_show.php">
なにこれ?

つかっていきます。
<?php
if($_POST["captcha_code"]){
require_once "securimage/securimage.php";
$securimage = new Securimage();
if($securimage->check($_POST['captcha_code'])==false){
echo "error";
} else {
echo "success";
}
}
?>
<form method="POST" name="form" action="">
<img id="captcha" src="securimage/securimage_show.php"><br>
<input type="text" name="captcha_code"><br>
<input type="submit" value="送信" class="submit">
</form>
おおおお

初期
.htaccess
192.168.33.11と192.168.33.12をアクセスdenyしています。

.htaccessの行数をカウントし、2行目から、最終行の前までをfgetsで1行ずつ取得し、新たに制限するipを追加して、file_put_contentsします。
$count = count(file(".htaccess"));
$file = fopen(".htaccess", "r");
$body = "<Files ~ \"^form\.php$\">\n";
$i = 0;
if($file){
while ($line = fgets($file)) {
$i++;
if($i < $count and $i !== 1){
$body .= $line;
}
}
}
$ip = "192.168.33.13";
$body .= "deny from ".$ip."\n";
$body .= "</Files>";
file_put_contents('.htaccess', $body);
.htaccessに、新たにdeny fromが追加されました。

今日から5営業日先までを表示したいとすると、今日が月曜日の場合は、strtotime(‘+1 day’)、strtotime(‘+2 day’), strtotime(‘+3 day’)…とすればいいが、土日をまたぐ場合は、strtotimeをその分追加する必要があるため、date(“w”)をswitch文で分ける。
$week = array( "日", "月", "火", "水", "木", "金", "土" );
switch(date("w")){
case 0:
$date = date("Y年m月d日", strtotime('+1 day'));
$today = $date."(".$week[date("w", strtotime('+1 day'))].")";
$date1 = date("m/d", strtotime('+1 day'));
$date1 = $date1."(".$week[date("w", strtotime('+1 day'))].")";
$date2 = date("m/d", strtotime('+2 day'));
$date2 = $date2."(".$week[date("w", strtotime('+2 day'))].")";
$date3 = date("m/d", strtotime('+3 day'));
$date3 = $date3."(".$week[date("w", strtotime('+3 day'))].")";
$date4 = date("m/d", strtotime('+4 day'));
$date4 = $date4."(".$week[date("w", strtotime('+4 day'))].")";
$date5 = date("m/d", strtotime('+5 day'));
$date5 = $date5."(".$week[date("w", strtotime('+5 day'))].")";
break;
case 1:
$date = date("Y年m月d日");
$today = $date."(".$week[date("w")].")";
$date1 = date("m/d");
$date1 = $date1."(".$week[date("w")].")";
$date2 = date("m/d", strtotime('+1 day'));
$date2 = $date2."(".$week[date("w", strtotime('+1 day'))].")";
$date3 = date("m/d", strtotime('+2 day'));
$date3 = $date3."(".$week[date("w", strtotime('+2 day'))].")";
$date4 = date("m/d", strtotime('+3 day'));
$date4 = $date4."(".$week[date("w", strtotime('+3 day'))].")";
$date5 = date("m/d", strtotime('+4 day'));
$date5 = $date5."(".$week[date("w", strtotime('+4 day'))].")";
break;
case 2:
$date = date("Y年m月d日");
$today = $date."(".$week[date("w")].")";
$date1 = date("m/d");
$date1 = $date1."(".$week[date("w")].")";
$date2 = date("m/d", strtotime('+1 day'));
$date2 = $date2."(".$week[date("w", strtotime('+1 day'))].")";
$date3 = date("m/d", strtotime('+2 day'));
$date3 = $date3."(".$week[date("w", strtotime('+2 day'))].")";
$date4 = date("m/d", strtotime('+3 day'));
$date4 = $date4."(".$week[date("w", strtotime('+3 day'))].")";
$date5 = date("m/d", strtotime('+6 day'));
$date5 = $date5."(".$week[date("w", strtotime('+6 day'))].")";
break;
case 3:
$date = date("Y年m月d日");
$today = $date."(".$week[date("w")].")";
$date1 = date("m/d");
$date1 = $date1."(".$week[date("w")].")";
$date2 = date("m/d", strtotime('+1 day'));
$date2 = $date2."(".$week[date("w", strtotime('+1 day'))].")";
$date3 = date("m/d", strtotime('+2 day'));
$date3 = $date3."(".$week[date("w", strtotime('+2 day'))].")";
$date4 = date("m/d", strtotime('+5 day'));
$date4 = $date4."(".$week[date("w", strtotime('+5 day'))].")";
$date5 = date("m/d", strtotime('+6 day'));
$date5 = $date5."(".$week[date("w", strtotime('+6 day'))].")";
break;
case 4:
$date = date("Y年m月d日");
$today = $date."(".$week[date("w")].")";
$date1 = date("m/d");
$date1 = $date1."(".$week[date("w")].")";
$date2 = date("m/d", strtotime('+1 day'));
$date2 = $date2."(".$week[date("w", strtotime('+1 day'))].")";
$date3 = date("m/d", strtotime('+4 day'));
$date3 = $date3."(".$week[date("w", strtotime('+4 day'))].")";
$date4 = date("m/d", strtotime('+5 day'));
$date4 = $date4."(".$week[date("w", strtotime('+5 day'))].")";
$date5 = date("m/d", strtotime('+6 day'));
$date5 = $date5."(".$week[date("w", strtotime('+6 day'))].")";
break;
case 5:
$date = date("Y年m月d日");
$today = $date."(".$week[date("w")].")";
$date1 = date("m/d");
$date1 = $date1."(".$week[date("w")].")";
$date2 = date("m/d", strtotime('+3 day'));
$date2 = $date2."(".$week[date("w", strtotime('+3 day'))].")";
$date3 = date("m/d", strtotime('+4 day'));
$date3 = $date3."(".$week[date("w", strtotime('+4 day'))].")";
$date4 = date("m/d", strtotime('+5 day'));
$date4 = $date4."(".$week[date("w", strtotime('+5 day'))].")";
$date5 = date("m/d", strtotime('+6 day'));
$date5 = $date5."(".$week[date("w", strtotime('+6 day'))].")";
break;
case 6:
$date = date("Y年m月d日", strtotime('+2 day'));
$today = $date."(".$week[date("w", strtotime('+2 day'))].")";
$date1 = date("m/d", strtotime('+2 day'));
$date1 = $date1."(".$week[date("w", strtotime('+2 day'))].")";
$date2 = date("m/d", strtotime('+3 day'));
$date2 = $date2."(".$week[date("w", strtotime('+3 day'))].")";
$date3 = date("m/d", strtotime('+4 day'));
$date3 = $date3."(".$week[date("w", strtotime('+4 day'))].")";
$date4 = date("m/d", strtotime('+5 day'));
$date4 = $date4."(".$week[date("w", strtotime('+5 day'))].")";
$date5 = date("m/d", strtotime('+6 day'));
$date5 = $date5."(".$week[date("w", strtotime('+6 day'))].")";
break;
}
上手く土日がスキップされています。月末、年末でも、strtotimeなので、処理を加える必要はありません。

パラメーターによって、予定も出し分けます。
if(!empty($_GET["d"])){
$date = date("Y年m月d日", strtotime("+".$_GET["d"]." day"));
$today = $date."(".$week[date("w", strtotime("+".$_GET["d"]." day"))].")";
}
4/6(金)

4/9(月)

Yes!
formへのリンク&Getパラメーターもつけて、大分出来てきました。次は管理画面側の設計と、担当者の個別ページの作成ですね。祝日の際の対応や、コメントの追加機能なども必要です。

absenceのテーブルをつくり、その日が休みの場合は、配列から削除する。
$sql3 = "select * from absence where day = '".$today."'";
$stmt3 = $dbh->query($sql3);
while($result3 = $stmt3->fetch(PDO::FETCH_ASSOC)){
$absence[] = $result3['name'];
}
foreach($absence as $value){
if(($key = array_search($value, $charge)) !== false) {
unset($charge[$key]);
}
}
$charge = array_values($charge);

$timelist = array(540, 570, 600, 630, 660, 690, 780, 810, 840, 870, 900, 930, 960, 990, 1020);
$list = array("予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可");
$list1 = array("予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可");
$list2 = array("予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可");
$charge = array('松島','小野','草野');
foreach($result as $value){
if($value['charge'] == $charge[0]){
for($i=0; $i < count($timelist); $i++){
if($timelist[$i] >= $value['time1'] and $timelist[$i] < $value['time2']){
$list[$i] = "×";
}
}
} elseif($value['charge'] == $charge[1]){
for($i=0; $i < count($timelist); $i++){
if($timelist[$i] >= $value['time1'] and $timelist[$i] < $value['time2']){
$list1[$i] = "×";
}
}
}elseif($value['charge'] == $charge[2]){
for($i=0; $i < count($timelist); $i++){
if($timelist[$i] >= $value['time1'] and $timelist[$i] < $value['time2']){
$list2[$i] = "×";
}
}
}
}
?>
<style>
#tbl-bdr table,#tbl-bdr td,#tbl-bdr th {
border-collapse: collapse;
border: 1px solid #000000;
}
table td{
width:45px;
}
</style>
<br>
<div id="tbl-bdr">
<table>
<tr>
<td></td><td>9:00~</td><td>9:30~</td><td>10:00~</td><td>10:30~</td><td>11:00~</td><td>11:30~</td><td>13:00~</td><td>13:30~</td><td>14:00~</td><td>14:30~</td><td>15:00~</td><td>15:30~</td><td>16:00~</td><td>16:30~</td><td>17:00~</td>
</tr>
<tr>
<td><?php echo $charge[0]; ?></td>
<?php
foreach($list as $value){
echo "<td>". $value."</td>";
}
?>
</tr>
<tr>
<td><?php echo $charge[1]; ?></td>
<?php
foreach($list1 as $value){
echo "<td>". $value."</td>";
}
?>
</tr>
<tr>
<td><?php echo $charge[2]; ?></td>
<?php
foreach($list2 as $value){
echo "<td>". $value."</td>";
}
?>
</tr>
</table>
表示はこれでほぼOK(最終版は、現在時刻以降を表示したい)なんだが、これ、どうやって書くんだ??

あ、$listはfor文の中に書いて、かつ、tdもfor文で回すのか???
名前ごとにforeachを回す仕様に書き換えました。
<style>
#tbl-bdr table,#tbl-bdr td,#tbl-bdr th {
border-collapse: collapse;
border: 1px solid #000000;
}
table td{
width:45px;
}
</style>
<br>
<div id="tbl-bdr">
<table>
<tr>
<td></td><td>9:00~</td><td>9:30~</td><td>10:00~</td><td>10:30~</td><td>11:00~</td><td>11:30~</td><td>13:00~</td><td>13:30~</td><td>14:00~</td><td>14:30~</td><td>15:00~</td><td>15:30~</td><td>16:00~</td><td>16:30~</td><td>17:00~</td>
</tr>
<?php
$charge = array('松島','小野','草野');
foreach($charge as $value){
echo "<tr><td>".$value. "</td>";
$timelist = array(540, 570, 600, 630, 660, 690, 780, 810, 840, 870, 900, 930, 960, 990, 1020);
$list = array("予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可");
foreach($result as $result1){
if($result1['charge'] == $value){
for($i=0; $i < count($timelist); $i++){
if($timelist[$i] >= $result1['time1'] and $timelist[$i] < $result1['time2']){
$list[$i] = "×";
}
}
}
}
foreach($list as $value){
echo "<td>".$value."</td>";
}
echo "</tr>";
}
?>
</table>
お!

formから草野さんに予約を入れます。

WoW!
次は、本日出勤の担当者のみ表示できるようにしたいですね。
mysql側で欠勤スケジュールのテーブルおよびdatepickerのformをつくります。