Не могу понять, как правильно анализировать массив JSON с помощью PHP.
В моем сценарии есть оператор foreach, который анализирует локальный файл JSON, извлекает данные и вставляет их в базу данных.
Все ок кроме разбора недели и рабочего времени.
Вот что я сделал:
$openingHours = $json_data['openingHours'];
каждый файл json может возвращать массив с разными строками, как в этом выводе:
example 1:
"openingHours" : [
"Su 09:00 - 23:59",
"Mo 00:00 - 23:59",
"Tu 00:00 - 13:00, 15:30 - 19:30",
"We 08:30 - 13:00, 15:30 - 19:30",
"Th 08:30 - 13:00, 15:30 - 19:30",
"Fr 08:30 - 13:00, 15:30 - 19:30",
"Sa 08:30 - 13:00, 15:30 - 19:30" ]
exampe 2:
"openingHours" : [
"Mo 08:00 - 13:00, 16:00 - 20:00",
"Tu 08:00 - 13:00, 16:00 - 20:00",
"We 08:00 - 13:00, 16:00 - 20:00",
"Th 08:00 - 13:00, 16:00 - 20:00",
"Fr 08:00 - 13:00, 16:00 - 20:00",
"Sa 08:00 - 13:00, 16:00 - 20:00" ]
example 3:
"openingHours" : [
"Mo 08:00 - 13:00, 16:00 - 20:00",
"We 08:00 - 13:00, 16:00 - 20:00",
"Th 08:00 - 13:00, 16:00 - 20:00",
"Sa 08:00 - 13:00, 16:00 - 20:00" ]
Как видите, в первом json у меня все 7 дней, во втором примере 6 дней с понедельника по субботу, а в третьем примере 4 дня Пн-Ср-Чт-Сб
Итак, я собираюсь создать оператор foreach для вывода данных;
foreach ($openingHours as $k_day=>$v_day) {
$openHrs = $openingHours[$k_day];
echo print_r($openHrs)."<br>";
}
он производит такой вывод:
FILE 1:
Mo 08:30 - 12:30, 16:00 - 20:00
Tu 08:30 - 12:30, 16:00 - 20:00
We 08:30 - 12:30, 16:00 - 20:00
Th 16:00 - 20:00
Fr 08:30 - 12:30, 16:00 - 20:00
Sa 08:30 - 12:30, 16:00 - 20:00
FILE 2:
Su 09:00 - 23:59
Mo 00:00 - 23:59
Tu 00:00 - 13:00, 15:30 - 19:30
We 08:30 - 13:00, 15:30 - 19:30
Th 08:30 - 13:00, 15:30 - 19:30
Sa 08:30 - 13:00, 15:30 - 19:30
FILE N:
.....
На данный момент мне нужно создать некоторые правила для правильного форматирования и извлечения дней и рабочих часов из массива.
Прежде всего, я должен объявить дни недели, которые начинаются с воскресенья.
0 - Su
1 - Mo
2 - Tu
3 - We
4 - Th
5 - Fr
6 - Sa
Затем проверьте, есть ли в массиве строки для всей недели (Вс - Пн - Вт...), и если какой-то день отсутствует, добавьте их в список в правильном месте.
Как в этом примере
"openingHours" : [
"Mo 08:00 - 13:00, 16:00 - 20:00",
"We 08:00 - 13:00",
"Th 08:00 - 13:00, 16:00 - 20:00",
"Sa 08:00 - 13:00, 16:00 - 20:00" ]
дни: Вс - Вт - Пт, не существует (это означает, что в эти дни Магазин закрыт).
В «среду» он открыт только с 08:00 до 13:00, а 3-го и 4-го временных интервалов нет. Это значит, что мне нужно вставить 2-х временные слоты. Очевидно, что для закрытых дней мне также нужно вставить временные интервалы ("00:00 - 00:00, 00:00 - 00:00").
0 - <-- insert
1 - Mo
2 - <-- insert
3 - We --> add "00:00 - 00:00"
4 - Th
5 - <-- insert
6 - Sa
Подводя итог, все строки дней и их слоты должны быть заполнены правильными данными.
Наконец, перед передачей данных в базу данных мне нужно правильно параметризовать переменные.
Это мой оператор CREATE TABLE таблицы, в которую я хочу поместить данные:
CREATE TABLE `business_hours_temp` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`place_id` INT(11) NOT NULL,
`day` INT(1) NOT NULL,
`open_1` TIME NOT NULL,
`close_1` TIME NOT NULL,
`open_2` TIME NOT NULL,
`close_2` TIME NOT NULL,
PRIMARY KEY (`id`),
INDEX `place_id` (`place_id`)
)
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=12;
и это оператор INSERT INTO
$stmt_hours = $conn->prepare(
'INSERT INTO business_hours_temp( place_id, day, open_1, close_1, open_2, close_2 )
VALUES(:place_id, :field_id, :field_value)');
$stmt_hours->bindValue(':place_id', $place_id);
$stmt_hours->bindValue(':day', $day);
$stmt_hours->bindValue(':open_1', $open_1);
$stmt_hours->bindValue(':close_1', $close_1);
$stmt_hours->bindValue(':open_2', $open_2);
$stmt_hours->bindValue(':close_2', $close_2);
$stmt_hours->execute();
Мне нужно получить вальс для $day - $open_1 - $close_1 - $open_2 - $close_2
Спасибо, ребята, за любую помощь.
Привет, приятель. Нет, часовые интервалы не совпадают. Это список местных предприятий, и у них могут быть разные временные интервалы.
Я бы изменил примеры, чтобы отразить это
Спасибо. Я знаю, что это немного сложная проблема.
<?php
$openingHours1 = [
"Su 09:00 - 23:59",
"Mo 00:00 - 23:59",
"Tu 00:00 - 13:00, 15:30 - 19:30",
"We 08:30 - 13:00, 15:30 - 19:30",
"Th 08:30 - 13:00, 15:30 - 19:30",
"Fr 08:30 - 13:00, 15:30 - 19:30",
"Sa 08:30 - 13:00, 15:30 - 19:30" ];
$openingHours3 = [
"Mo 08:00 - 13:00, 16:00 - 20:00",
"We 08:00 - 13:00, 16:00 - 20:00",
"Th 08:00 - 13:00, 16:00 - 20:00",
"Sa 08:00 - 13:00, 16:00 - 20:00" ];
$openingHours2 = [
"Mo 08:00 - 13:00, 16:00 - 20:00",
"Tu 08:00 - 13:00, 16:00 - 20:00",
"We 08:00 - 13:00, 16:00 - 20:00",
"Th 08:00 - 13:00, 16:00 - 20:00",
"Fr 08:00 - 13:00, 16:00 - 20:00",
"Sa 08:00 - 13:00, 16:00 - 20:00" ];
function parse($openingHours)
{
$resultList = [];
$daysLut = [
'Su' => 0,
'Mo' => 1,
'Tu' => 2,
'We' => 3,
'Th' => 4,
'Fr' => 5,
'Sa' => 6,
];
$counter = 0;
$dayNoLut = [];
foreach ($openingHours as $oppening) {
$open1 = null;
$open2 = null;
$dayLetter = substr($oppening, 0, 2);
$dayNo = $daysLut[$dayLetter];
$open1 = substr($oppening, 3, 13);
if (strlen($oppening) > 18) {
$open2 = substr($oppening, 18);
}
if (empty($open2)) {
$open2 = "00:00 - 00:00";
}
$result['dayNo'] = $dayNo;
$result['open1'] = $open1;
$result['open2'] = $open2;
$dayNoLut[$dayNo] = $counter;
$resultList[] = $result;
$counter++;
}
$resultFilledList = [];
$resultListCount = count($resultList);
if ($resultListCount < 7) {
$result = [];
$result['open1'] = "00:00 - 00:00";
//remove this line if for a cloed day you want only one 00:00 - 00:00
$result['open2'] = "00:00 - 00:00";
for($i=0; $i<7; $i++) {
$result['dayNo'] = $i;
if (key_exists($i, $dayNoLut)) {
$resultFilledList[$i] = $resultList[$dayNoLut[$i]];
} else {
$resultFilledList[$i] = $result;
}
}
} else {
$resultFilledList = $resultList;
}
return $resultFilledList;
}
$resultFilledList = parse($openingHours3);
print_r($resultFilledList);
$daysLut2 = [
0 => 'Su',
1 => 'Mo',
2 => 'Tu',
3 => 'We',
4 => 'Th',
5 => 'Fr',
6 => 'Sa',
];
$lineList = [];
foreach($resultFilledList as $result) {
$line = '';
$line .= $daysLut2[$result['dayNo']];
$line .= ' ' . $result['open1'];
$line .= ', ' . $result['open2'];
$lineList[] = $line;
}
print_r($lineList);
$lineList = [];
foreach($resultFilledList as $result) {
$line = '';
$line = $result['dayNo'];
$line .= ' - ';
$line .= $daysLut2[$result['dayNo']];
$line .= ' ' . $result['open1'];
$line .= ', ' . $result['open2'];
$lineList[] = $line;
}
print_r($lineList);
дает вывод:
Array
(
[0] => Array
(
[open1] => 00:00 - 00:00
[open2] => 00:00 - 00:00
[dayNo] => 0
)
[1] => Array
(
[dayNo] => 1
[open1] => 08:00 - 13:00
[open2] => 16:00 - 20:00
)
[2] => Array
(
[open1] => 00:00 - 00:00
[open2] => 00:00 - 00:00
[dayNo] => 2
)
[3] => Array
(
[dayNo] => 3
[open1] => 08:00 - 13:00
[open2] => 16:00 - 20:00
)
[4] => Array
(
[dayNo] => 4
[open1] => 08:00 - 13:00
[open2] => 16:00 - 20:00
)
[5] => Array
(
[open1] => 00:00 - 00:00
[open2] => 00:00 - 00:00
[dayNo] => 5
)
[6] => Array
(
[dayNo] => 6
[open1] => 08:00 - 13:00
[open2] => 16:00 - 20:00
)
)
Array
(
[0] => Su 00:00 - 00:00, 00:00 - 00:00
[1] => Mo 08:00 - 13:00, 16:00 - 20:00
[2] => Tu 00:00 - 00:00, 00:00 - 00:00
[3] => We 08:00 - 13:00, 16:00 - 20:00
[4] => Th 08:00 - 13:00, 16:00 - 20:00
[5] => Fr 00:00 - 00:00, 00:00 - 00:00
[6] => Sa 08:00 - 13:00, 16:00 - 20:00
)
Array
(
[0] => 0 - Su 00:00 - 00:00, 00:00 - 00:00
[1] => 1 - Mo 08:00 - 13:00, 16:00 - 20:00
[2] => 2 - Tu 00:00 - 00:00, 00:00 - 00:00
[3] => 3 - We 08:00 - 13:00, 16:00 - 20:00
[4] => 4 - Th 08:00 - 13:00, 16:00 - 20:00
[5] => 5 - Fr 00:00 - 00:00, 00:00 - 00:00
[6] => 6 - Sa 08:00 - 13:00, 16:00 - 20:00
)
просто используйте
$resultFilledList = parse($openingHours3);
где oppeningHours3
— массив. поэтому, если у вас есть это в json, используйте $openingHours3 = json_decode($data, true);
,
а потом
напечатайте его или повторите его с помощью цикла foreach, как я сделал в своем коде.
Спасибо, Джиммикс, я проверю и дам вам знать, если это сработает... еще раз спасибо, я очень ценю это.
Спасибо, Джиммикс! Оно работает!
Я просто делаю небольшие изменения, чтобы поймать значения переменных, которые мне нужны. В коде есть комментарии. Спасибо еще раз.
foreach($resultFilledList as $result) {
$line = '';
$line .= $daysLut2[$result['dayNo']];
$line .= ' ' . $result['open1'];
$line .= ', ' . $result['open2'];
$lineList[] = $line;
//FOR STORING DATA IN DB
//get DAY - INT
$day = $daysLut2[$result['dayNo']];
// SPLIT/EXPLODE Main slot 1 and 2
// and get time_slot 1,2, 3 and 4
// trim the EXPLODE and add ":00" for proper MySQL TIME type
$main_slot_1 = $result['open1'];
$main_slot_1_expl = explode('-',$main_slot_1,2);
$main_slot_2 = $result['open2'];
$main_slot_2_expl = explode('-',$main_slot_2,2);
$time_slot_1 = trim($main_slot_1_expl[0], ' ').":00";
$time_slot_2 = trim($main_slot_1_expl[1], ' ').":00";
$time_slot_3 = trim($main_slot_2_expl[0], ' ').":00";
$time_slot_4 = trim($main_slot_2_expl[1], ' ').":00";
}
И часы всегда одинаковы для любого заданного json?