祝日判定 new HolidayDateTime()

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>

うわー

画像認証 securimage

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&#91;"captcha_code"&#93;){
	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>

おおおお

phpで.htaccessに制限するipアドレスを追加する

初期
.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営業日先までを出し分ける

今日から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);

tableにスケジュールを入れていく2

$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&#91;$i&#93; >= $value['time1'] and $timelist[$i] < $value&#91;'time2'&#93;){
			 $list&#91;$i&#93; = "×";
		}
	   }
	} elseif($value&#91;'charge'&#93; == $charge&#91;1&#93;){
		for($i=0; $i < count($timelist); $i++){
		if($timelist&#91;$i&#93; >= $value['time1'] and $timelist[$i] < $value&#91;'time2'&#93;){
			 $list1&#91;$i&#93; = "×";
		}
	   } 
	}elseif($value&#91;'charge'&#93; == $charge&#91;2&#93;){
		for($i=0; $i < count($timelist); $i++){
		if($timelist&#91;$i&#93; >= $value['time1'] and $timelist[$i] < $value&#91;'time2'&#93;){
			 $list2&#91;$i&#93; = "×";
		}
	  }
	 }
}

?>
<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&#91;0&#93;; ?></td>
<?php
	foreach($list as $value){
		echo "<td>". $value."</td>";
	}	
?>
</tr>
<tr>
<td><?php echo $charge&#91;1&#93;; ?></td>
<?php
	foreach($list1 as $value){
		echo "<td>". $value."</td>";
	}	
?>
</tr>
<tr>
<td><?php echo $charge&#91;2&#93;; ?></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&#91;$i&#93; >= $result1['time1'] and $timelist[$i] < $result1&#91;'time2'&#93;){
				 $list&#91;$i&#93; = "×";
			} 
		  }
		}
	 }

	 foreach($list as $value){
	 	echo "<td>".$value."</td>";
	 }
 echo "</tr>";
}
?>
</table>

お!

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

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

tableにスケジュールを入れていく

初期画面

<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>12:00</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>松島</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
</tr>
<tr>
<td>小野</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
</tr>
<tr>
<td>草野</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td>
</tr>
</table>
</div>

テーブルはできたんですが、ここからどうすればいいのでしょうか?

セル毎にデフォルトは〇、if文でその時間帯が開始時間と終了時間の間であれば×を計算でしょうか。
いや、予約が入っているところだけ、計算した方が速いような気がします。
なんか凄い難しいぞ。
あ、仮置きで、9:00->a 9:30->b, 10:00->c, 10:30->d .. として、aが〇か×か判定の判定をfor文で回せばいいのでしょうか? いや、for文で回すと$iと$jを入れ子で回すので、担当者のid(テーブル)を作る必要がありそうです。

あ、こういうことですかね?

$timelist = array(540, 570, 600, 630, 660, 690, 780, 810, 840, 870, 900, 930, 960, 990, 1020);

for($i=0; $i < count($timelist); $i++){
	if($timelist&#91;$i&#93; >= $result[0]['time1'] and $timelist[$i] < $result&#91;0&#93;&#91;'time2'&#93;){
		echo "予約あり<br>";
	}else{
		echo "予約なし<br>";
	}
}

小野:10:00~11:00 (60分)
予約なし
予約なし
予約あり
予約あり
予約なし
予約なし
予約なし
予約なし
予約なし
予約なし
予約なし
予約なし
予約なし
予約なし
予約なし

修正します。

$timelist = array(540, 570, 600, 630, 660, 690, 780, 810, 840, 870, 900, 930, 960, 990, 1020);
$list = array("予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可","予約可");

foreach($result as $value){
	for($i=0; $i < count($timelist); $i++){
	if($timelist[$i] >= $value['time1'] and $timelist[$i] < $value['time2']){
		 $list[$i] = "×";
	}
 }
}

a little close?

更に修正

今日の予約状況を表示する

order by time1 ascで予約の早い時間から表示する

<?php

$date = date("Y年m月d日");
$week = array( "日", "月", "火", "水", "木", "金", "土" );
$today = $date."(".$week&#91;date("w")&#93;.")";
echo "本日の予約状況(".$today.")<hr>";

$dsn = "mysql:dbname=reserve;host=localhost";
$user = "hoge";
$password = "hogehoge";	 
try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e){
    print('connection failed:'.$e->getMessage());
} 

$sql = "select * from masters where day = '".$today."' order by time1 asc";
$stmt = $dbh->query($sql);
 
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach($result as $value){
	$t1h = floor($value['time1'] / 60);
	$t1m = $value['time1'] % 60;
	if(!$t1m == NUll ){
		$t1 = $t1h.":".$t1m;
	}else{
		$t1 = $t1h.":00";
	}
	$t2h = floor($value['time2'] / 60);
	$t2m = $value['time2'] % 60;
	if(!$t2m == NUll ){
		$t2 = $t2h.":".$t2m;
	}  else {
		$t2 = $t2h.":00";
	}
	echo $value['charge']. ":".$t1."~".$t2." ".$value['name']."様<br>";
}

ホットペッパーのような〇×のマトリックスを横軸で作りたいですね。

ソースを見ると、普通にtable tr tdのようです。

予約時間のバリデーション

予約希望が入った場合は、whereでその日の担当者の予約済時間帯を参照する。
希望開始時間が予約済開始時間~予約済終了時間の間、もしくは、
希望終了時間が予約済開始時間~予約済終了時間の間の場合は、予約できないようにする。

    $validation = 0;
    $sql = "select * from masters where day = '".$day."' and charge = '".$charge."'";
	$stmt = $dbh->query($sql);
	 
	$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
 
	foreach($result as $value){
		if($time1 >= $value["time1"] and $time1 <= $value&#91;"time2"&#93;){
			$validation = 1;
		} elseif($time2 >= $value["time1"] and $time2 <= $value&#91;"time2"&#93;){
			$validation = 1;
		}
	}
&#91;/php&#93;


viewはif, elseifで表示を切り分ける。
&#91;php&#93;
<?php if($validation == 0): ?>
<?php elseif($validation == 1): ?>
<?php endif; ?>

予約済み時間との間を30分あける場合などは、$time1 >= $value[“time1”] and $time1 <= $value["time2"]を変更すればよい。 あれ? 思ってたより直ぐできた?

次は予約一覧の表示ですね。