我编写了一些代码来从数据库中检索不同餐厅的不同工作时间,并显示它们现在是否开放。
工作时间定义如下:10:30to13:30/18:30to22:30
.
问题是我找不到一个简短的方法来编写下面所有的代码。我怎样才能缩短它的长度?
if ($result > 0) {
while($row = $stmt->fetch()) {
//SETUP HOURS FOR EACH DAY
$timesSun = $row['sunday'];
$timesMon = $row['monday'];
$timesTue = $row['tuesday'];
$timesWed = $row['wednesday'];
$timesThu = $row['thursday'];
$timesFri = $row['friday'];
$timesSat = $row['saturday'];
//SEPARATE DAY & NIGHT
$sepDNsun = explode('/',$timesSun);
$sepDNmon = explode('/',$timesMon);
$sepDNtue = explode('/',$timesTue);
$sepDNwed = explode('/',$timesWed);
$sepDNthu = explode('/',$timesThu);
$sepDNfri = explode('/',$timesFri);
$sepDNsat = explode('/',$timesSat);
//SEPARATE OPEN AND CLOSE
$daySun = explode('to',$sepDNsun[0]);
$nightSun = explode('to',$sepDNsun[1]);
$dayMon = explode('to',$sepDNmon[0]);
$nightMon = explode('to',$sepDNmon[1]);
$dayTue = explode('to',$sepDNtue[0]);
$nightTue = explode('to',$sepDNtue[1]);
$dayWed = explode('to',$sepDNwed[0]);
$nightWed = explode('to',$sepDNwed[1]);
$dayThu = explode('to',$sepDNthu[0]);
$nightThu = explode('to',$sepDNthu[1]);
$dayFri = explode('to',$sepDNfri[0]);
$nightFri = explode('to',$sepDNfri[1]);
$daySat = explode('to',$sepDNsat[0]);
$nightSat = explode('to',$sepDNsat[1]);
//SET OPEN & CLOSE
$dayOpenSun = $daySun[0];
$dayCloseSun = $daySun[1];
$nightOpenSun = $nightSun[0];
$nightCloseSun = $nightSun[1];
$dayOpenMon = $dayMon[0];
$dayCloseMon = $dayMon[1];
$nightOpenMon = $nightMon[0];
$nightCloseMon = $nightMon[1];
$dayOpenTue = $dayTue[0];
$dayCloseTue = $dayTue[1];
$nightOpenTue = $nightTue[0];
$nightCloseTue = $nightTue[1];
$dayOpenWed = $dayWed[0];
$dayCloseWed = $dayWed[1];
$nightOpenWed = $nightWed[0];
$nightCloseWed = $nightWed[1];
$dayOpenThu = $dayThu[0];
$dayCloseThu = $dayThu[1];
$nightOpenThu = $nightThu[0];
$nightCloseThu = $nightThu[1];
$dayOpenFri = $dayFri[0];
$dayCloseFri = $dayFri[1];
$nightOpenFri = $nightFri[0];
$nightCloseFri = $nightFri[1];
$dayOpenSat = $daySat[0];
$dayCloseSat = $daySat[1];
$nightOpenSat = $nightSat[0];
$nightCloseSat = $nightSat[1];
//SET STORE OPENING HOURS
$storeSchedule = [
'Sun' => [$dayOpenSun => $dayCloseSun, $nightOpenSun => $nightCloseSun],
'Mon' => [$dayOpenMon => $dayCloseMon, $nightOpenMon => $nightCloseMon],
'Tue' => [$dayOpenTue => $dayCloseTue, $nightOpenTue => $nightCloseTue],
'Wed' => [$dayOpenWed => $dayCloseWed, $nightOpenWed => $nightCloseWed],
'Thu' => [$dayOpenThu => $dayCloseThu, $nightOpenThu => $nightCloseThu],
'Fri' => [$dayOpenFri => $dayCloseFri, $nightOpenFri => $nightCloseFri],
'Sat' => [$dayOpenSat => $dayCloseSat, $nightOpenSat => $nightCloseSat]
];
// current or user supplied UNIX timestamp
$timestamp = time();
// default status
$status = $lang["NO-READY"];
// get current time object
$currentTime = (new DateTime())->setTimestamp($timestamp);
// loop through time ranges for current day
foreach ($storeSchedule[date('D', $timestamp)] as $startTime => $endTime) {
// create time objects from start/end times
$startTime = DateTime::createFromFormat('G:i', $startTime);
$endTime = DateTime::createFromFormat('G:i', $endTime);
// check if current time is within a range
if (($startTime < $currentTime) && ($currentTime < $endTime)) {
$status = $lang["READY"];
break;
}
}
//OUTPUT CONTENT
echo '<li>
<div class="rest-list-content">
<a href="'. $location .'/restaurants/'. $row["rest_url"] .'">
<img src="images/all_rest/'. $row["rest_logo"] .'" alt="'. $row["rest_name"] .'">
<h1>'. $row["rest_name"] .'</h1>
<p>Cuisine: <span>'. $row["cuisine_name"] .'</span></p>
<p>Minimun Order: <span>$'. $row["rest_min_order"] .'</span></p>
<p class="availability">'. $status .'</p>
</a>
</div>
</li>';
}
} else {
echo "0 results";
}
引言
我可能错了,但是看看这段代码,似乎你正在做的是显示餐馆现在是否开业。
这里有很多需要优化的地方:
- 您不断重新声明
$timestamp = time();
和与之相关的其他变量。这是相当低效的,因为在脚本执行期间时间不会改变太多。即使脚本运行时间超过一秒钟,这也可以忽略不计。必须在循环之前声明一次。 - 你处理一周的所有7天,而你只需要与今天对应的一天,我们可以减少85%的工作量。
- 这么多独特的变量。这可以大大减少。数组是我们的朋友。
让我们减少
$currentTime = new DateTime('now');
$currentDay = strtolower($currentTime->format('l'));
if($result > 0) {
while($row = $stmt->fetch()) {
$schedule = explode('/',
str_replace('to', '/', $row[$currentDay])
);
foreach($schedule as $time) {
$schedule['time'][] = DateTime::createFromFormat('G:i', $time);
}
$status =
($schedule['time'][0] <= $currentTime && $currentTime <= $schedule['time'][1])
||
($schedule['time'][2] <= $currentTime && $currentTime <= $schedule['time'][3])
? $lang["READY"]
: $lang["NO-READY"];
/*
HTML GOES HERE
*/
}
}
else {
echo '0 results';
}
发生了什么由于日期和时间在脚本执行过程中不太可能改变,因此我们将这部分移到了开头。
这返回一个
DateTime
对象为"现在",不需要调用time()
:$currentTime = new DateTime('now');
返回今天的完整文本日期,将其转换为小写以匹配数据库记录(例如:
tuesday
):$currentDay = strtolower($currentTime->format('l'));
对于迭代的每条记录:
- 我们使用
$row[$currentDay]
,这是今天的数据。 - 我们用
/
代替to
,结果是xx:xx/xx:xx/xx:xx/xx:xx
。 我们使用
/
爆炸。$schedule = explode('/', str_replace('to', '/', $row[$currentDay]) );
我们现在有一个包含4个值的数组:
Array ( [0] => 9:30 [1] => 13:30 [2] => 17:30 [3] => 20:30 )
我们根据这些值分别创建一个
DateTime
对象,并将它们存储在同一个数组中:foreach($schedule as $time) { $schedule['time'][] = DateTime::createFromFormat('G:i', $time); }
我们现在有了这个数组:
Array ( [0] => 9:30 [1] => 13:30 [2] => 17:30 [3] => 20:30 [time] => Array ( [0] => DateTime Object ( [date] => 2015-09-29 09:30:00.000000 [timezone_type] => 3 [timezone] => Europe/Paris ) [1] => DateTime Object ( [date] => 2015-09-29 13:30:00.000000 [timezone_type] => 3 [timezone] => Europe/Paris ) [2] => DateTime Object ( [date] => 2015-09-29 17:30:00.000000 [timezone_type] => 3 [timezone] => Europe/Paris ) [3] => DateTime Object ( [date] => 2015-09-29 20:30:00.000000 [timezone_type] => 3 [timezone] => Europe/Paris ) ) )
我们使用一个三元操作符来设置状态(
true ? true : false
)。
这检查"现在"是否同时在早晨或晚上时间之间。$status = ($schedule['time'][0] <= $currentTime && $currentTime <= $schedule['time'][1]) || ($schedule['time'][2] <= $currentTime && $currentTime <= $schedule['time'][3]) ? $lang["READY"] : $lang["NO-READY"];
$status
现在可用,html可以构建了重复,直到没有记录。
- 我们使用
退出循环
做完了。