Это ошибка, которую я получаю.
Неустранимая ошибка: допустимый объем памяти исчерпан.
Я собираю массивы, содержащие дату from
и свидание till
, Я пытаюсь получить все даты между ними и добавить их в новый массив. Видимо, вложенные циклы и мульти-массивы истощают.
Мне нужен менее изнурительный способ получить все свидания.
Это мой код:
$query = "SELECT *
FROM reservate
ORDER BY from";
$result = $connect->query($query);
$reservations = array();
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$reservations[] = $row;
}
}
$connect->close();
//AVAILABILITY CHECK
$nonAvailable = array();
foreach($reservations as $reservation){
$from = $reservation['from'];
$till = $reservation['till'];
while($from <= $till){
$nonAvailable[] = $from;
$from = date('Y-m-d', strtotime("+1 days"));
}
}
Похоже, вы сделали бесконечный цикл1.
// if $till is in the future, this is an infinite loop
while($from <= $till){
// appending the same value of $from on each iteration
$nonAvailable[] = $from;
// as $from never changes value
$from = date('Y-m-d', strtotime("+1 days"));
}
добавлять 1
день до текущей стоимости $from
while ($from <= $till){
$nonAvailable[] = $from;
// add 1 day to $from
$from = date('Y-m-d', strtotime($from, "+1 days"));
}
Есть еще несколько улучшений, которые можно сделать:
reservation
массив и мы только извлекаем нужные нам столбцыintegers
вместо strings
,
1
день до $from
скорее вручную, чем полагаясь на strtotime
сделать это.
$query = "SELECT from, till
FROM reservate
ORDER BY from";
$result = $connect->query($query);
$nonAvailable = array();
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
$from = strtotime($row['from']);
$till = strtotime($row['till']);
while ($from <= $till) {
$nonAvailable[] = date('Y-m-d', $from);
$from += 60*60*24;
}
}
}
$connect->close();
Вполне вероятно, что этот алгоритм можно сделать гораздо более эффективным. Например, вам нужен исчерпывающий список на каждый день, что-то зарезервировано? Если нет, то достаточно даты начала и окончания.
1 При наличии достаточного времени и памяти цикл завершится как strtotime("+1 days")
в конечном итоге вернет значение больше $till
,
Альтернативный способ сделать это, используя только один запрос.
Это берет вашу таблицу бронирования и перекрестно соединяет ее с парой подзапросов, которые получают диапазоны чисел. Каждый получает числа от 0 до 9, и один используется как единицы, а один — как десятки. В сочетании они дают цифры от 0 до 99 (таким образом, диапазон 99 дней).
Предложение WHERE просто проверяет, что дата от даты (фургон) плюс количество дней (от 0 до 99) меньше или равна дате до (общая). Следовательно, комната (я предполагаю, что несколько комнат или какой-то другой предмет, который забронирован) выдается с каждой датой, когда она забронирована:
SELECT room, DATE_ADD(van, INTERVAL (tens.i * 10 + units.i) DAY) AS non_available
FROM reservate
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
WHERE DATE_ADD(van, INTERVAL (tens.i * 10 + units.i) DAY) <= tot
ORDER BY room, non_available
Пример скрипты SQL: —
http://www.sqlfiddle.com/#!9/83054/1
Вы можете использовать таблицу целых чисел вместо 2 подзапросов.