首页 > 解决方案 > 使用 PHP 从 JSON 数组中解析营业时间时隙和工作日

问题描述

无法弄清楚如何使用 PHP 正确解析 JSON 数组。

在我的脚本中,我有一个解析本地 JSON 文件、提取数据并将其插入数据库的 foreach 语句。

除了解析星期和营业时间外,一切都很好。

这就是我所做的:

$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 天 Mo-We-Th-Sa

所以我要创建一个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

然后,检查数组中是否有所有星期字符串(Su - Mo -Tu...),如果缺少某一天,请将它们添加到列表中的正确位置。

如本例

"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" ]

日子:Su - Tu - Fr,不存在(这意味着在这些日子里商店关门了)。

在“星期三”,它只在 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();

我需要得到 vals$day - $open_1 - $close_1 - $open_2 - $close_2

谢谢你们的帮助。

标签: phpmysqlarraysjson

解决方案


<?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 循环打印或迭代它。


推荐阅读