Анализировать рабочие часы, временные интервалы и дни недели из массива JSON с помощью PHP

Не могу понять, как правильно анализировать массив 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

Спасибо, ребята, за любую помощь.

И часы всегда одинаковы для любого заданного json?

Strawberry 27.05.2019 14:02

Привет, приятель. Нет, часовые интервалы не совпадают. Это список местных предприятий, и у них могут быть разные временные интервалы.

Alexandr Misiyuk 27.05.2019 14:05

Я бы изменил примеры, чтобы отразить это

Strawberry 27.05.2019 14:15

Спасибо. Я знаю, что это немного сложная проблема.

Alexandr Misiyuk 27.05.2019 14:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
4
687
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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, как я сделал в своем коде.

Спасибо, Джиммикс, я проверю и дам вам знать, если это сработает... еще раз спасибо, я очень ценю это.

Alexandr Misiyuk 27.05.2019 16:12
Ответ принят как подходящий

Спасибо, Джиммикс! Оно работает!

Я просто делаю небольшие изменения, чтобы поймать значения переменных, которые мне нужны. В коде есть комментарии. Спасибо еще раз.

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";
    }

Другие вопросы по теме