Хорошо, поэтому, чтобы сделать его коротким. Вложенные функции - грязное дело. Ваша ошибка выглядит следующим образом: Вы запускаете родительскую функцию. Когда это выполняется, оно регистрирует вложенные функции. Именно поэтому в первый раз у вас нет проблем. Однако при повторном запуске родительского элемента php выдаст ошибку, сообщив, что вложенные функции уже существуют, поскольку они пытаются зарегистрировать их снова.
Если вам необходимо сохранить свой код, вы можете проверить, была ли функция уже зарегистрирована.
function open_closed_message() {
date_default_timezone_set('America/Toronto');
$date = new DateTime;
echo date("D m/d/y h:i:s ",time());
$times = array(
'mon' => '9:00 AM - 9:00 PM',
'tue' => '9:00 AM - 9:00 PM',
'wed' => '9:00 AM - 9:00 PM',
'thu' => '9:00 AM - 9:00 PM',
'fri' => '9:00 AM - 9:00 PM',
'sat' => '11:00 AM - 6:00 PM',
'sun' => 'closed'
);
// Check if function exists
if (!function_exists('compileHours')) {
function compileHours($times, $timestamp) {
$times = $times[strtolower(date('D',$timestamp))];
if(!strpos($times, '-')) return array();
$hours = explode(",", $times);
$hours = array_map('explode', array_pad(array(),count($hours),'-'), $hours);
$hours = array_map('array_map', array_pad(array(),count($hours),'strtotime'), $hours, array_pad(array(),count($hours),array_pad(array(),2,$timestamp)));
end($hours);
if ($hours[key($hours)][0] > $hours[key($hours)][1]) $hours[key($hours)][1] = strtotime('+1 day', $hours[key($hours)][1]);
return $hours;
}
}
// Check if function exists
if (!function_exists('isOpen')) {
function isOpen($now, $times) {
$open = 0; // time until closing in seconds or 0 if closed
// merge opening hours of today and the day before
$hours = array_merge(compileHours($times, strtotime('yesterday',$now)),compileHours($times, $now));
foreach ($hours as $h) {
if ($now >= $h[0] and $now < $h[1]) {
$open = $h[1] - $now;
return $open;
}
}
return $open;
}
}
$now = time();
$open = isOpen($now, $times);
if ($open == 0) {
echo "Closed - Sorry, we are not making deliveries.";
}
elseif ($open <= 1800) {
$tomorrow = strtotime('tomorrow', $now);
if (date('N', $tomorrow) == 7) {
$tomorrow = strtotime('next monday', $now);
}
$day = strtolower(date('D', $tomorrow));
$tomorrow = date('l', $tomorrow);
$opentime = preg_replace('/^(\d+:\d+ [AP]M).*/', '$1', $times[$day]);
echo "Finishing up current orders. We re-open $tomorrow at $opentime";
}
else {
echo "Open - Yes, we are making deliveries.";
}
}
или вы можете создать класс. что было бы намного лучше
class open_closed_message{
public $date;
public $times;
public function __construct(){
date_default_timezone_set('America/Toronto');
$this->date = new DateTime;
$this->times = [
'mon' => '9:00 AM - 9:00 PM',
'tue' => '9:00 AM - 9:00 PM',
'wed' => '9:00 AM - 9:00 PM',
'thu' => '9:00 AM - 9:00 PM',
'fri' => '9:00 AM - 9:00 PM',
'sat' => '11:00 AM - 6:00 PM',
'sun' => 'closed'
];
}
public function message(){
echo date("D m/d/y h:i:s ",time());
$now = time();
$open = $this->isOpen($now, $this->times);
if ($open == 0) {
echo "Closed - Sorry, we are not making deliveries.";
} elseif ($open <= 1800) {
$tomorrow = strtotime('tomorrow', $now);
if (date('N', $tomorrow) == 7) {
$tomorrow = strtotime('next monday', $now);
}
$day = strtolower(date('D', $tomorrow));
$tomorrow = date('l', $tomorrow);
$opentime = preg_replace('/^(\d+:\d+ [AP]M).*/', '$1', $this->times[$day]);
echo "Finishing up current orders. We re-open $tomorrow at $opentime";
}
else {
echo "Open - Yes, we are making deliveries.";
}
}
private function compileHours($times, $timestamp){
$times = $times[strtolower(date('D',$timestamp))];
if(!strpos($times, '-')) return array();
$hours = explode(",", $times);
$hours = array_map('explode', array_pad(array(),count($hours),'-'), $hours);
$hours = array_map('array_map', array_pad(array(),count($hours),'strtotime'), $hours, array_pad(array(),count($hours),array_pad(array(),2,$timestamp)));
end($hours);
if ($hours[key($hours)][0] > $hours[key($hours)][1]) $hours[key($hours)][1] = strtotime('+1 day', $hours[key($hours)][1]);
return $hours;
}
private function isOpen($now, $times) {
$open = 0; // time until closing in seconds or 0 if closed
// merge opening hours of today and the day before
$hours = array_merge(compileHours($times, strtotime('yesterday',$now)),compileHours($times, $now));
foreach ($hours as $h) {
if ($now >= $h[0] and $now < $h[1]) {
$open = $h[1] - $now;
return $open;
}
}
return $open;
}
}
запустить класс
$openClose = new open_closed_message();
запустить метод
$openClose->message();