将 3D 数组数据打印为每天时间范围的 HTML 表格

问题描述 投票:0回答:2

我有一个多维数组,如下所示。我想在表格中显示数据,将一周中的每一天及其开始和结束时间显示在一行中。下表附有预期结果。

我对数组不熟悉,所以我还没有真正尝试过任何值得一提的东西。

$times = [
    "opening_time" => [
        "monday" => ["10:30 am", "6:30 pm"],
        "tuesday" => ["12:30 pm"],
        "wednesday" => ["4:30 pm"],
        "thursday" => ["2:30 pm"],
        "friday" => ["4:00 pm"],
        "saturday" => ["6:00 am"],
        "sunday" => []
    ],
    "closing_time" => [
        "monday" => ["6:00 pm", "10:30 pm"],
        "tuesday" => ["7:00 pm"],
        "wednesday" => ["10:00 pm"],
        "thursday" => ["6:30 pm"],
        "friday" => ["11:00 pm"],
        "saturday" => ["6:00 pm"],
        "sunday" => []
    ]
];
 

php arrays loops multidimensional-array html-table
2个回答
1
投票

你可以这样做。请阅读代码中的注释以及输出下面的注释。

<?php
function renderSlots($columns,$repacked,$day,$time) {
    $html = '';
    for($i = 0; $i < $columns; $i++) {
        // Check if slot i is set
        if(isset($time[0][$i])) {
            $html .= '
                <td>'.$time[0][$i].' to '.$repacked[$day]["closing_time"][0][$i].'</td>
            ';
        } else {
            $html .= '
                <td></td>
            ';
        }
    }

    return $html;
}

$times = [
    "opening_time" =>[
        "monday" => [
            0 => "10:00 am",
            1 => "6:30 pm",
            2 => "some other time"
        ],
        "tuesday" => [
            0 => "12:30 pm"
        ],
        "wednesday" => [
            0 => "4:30 pm"
        ],
        "thursday" => [
            0 => "2:30 pm"
        ],
        "friday" => [
            0 => "4:00 pm"
        ],
        "saturday" => [
            0 => "6:00 am"
        ],
        "sunday" => []
    ],
    "closing_time" => [
        "monday" => [
            0 => "6:00 pm",
            1 => "10:30 pm",
            2 => "some other closing time"
        ],
        "tuesday" => [
            0 => "7:00 pm"
        ],
        "wednesday" => [
            0 => "10:00 pm"
        ],
        "thursday" => [
            0 => "6:30 pm"
        ],
        "friday" => [
            0 => "11:00 pm"
        ],
        "saturday" => [
            0 => "6:00 pm"
        ],
        "sunday" => []
    ]
];

// Repacking your original array to be like this
/*
    $arr = [
        day => [
            opening_time => [
                10:00 am
                6:30 pm
            ],
            closing_time => [
                6:00 pm
                10:30 pm
            ]
        ]
        ...
    ];
*/

$repacked = [];

// This is to determine the number of columns we'll need
// Letters a-g are variables, standing in for the number of
// slots in a day
/*
$arr = [
    "monday" => a,
    "tuesday" => b,
    "wednesday" => c,
    "thursday" => d,
    "friday" => e,
    "saturday" => f,
    "sunday" => g 
];
*/
$daySlots = [];


foreach($times as $type=>$days) {
    foreach($days as $day=>$time) {
        if(!isset($repacked[$day][$type])) {
            $repacked[$day][$type] = [];
        }

        $repacked[$day][$type][] = $time;

        if(!isset($daySlots[$day])) {
            $daySlots[$day] = 0;
        }

        $daySlots[$day] = count($time);
    }
}

// Get the max number of work slots
$columns = max($daySlots);

$html = '
    <table>
        <thead>
            <tr>
                <th>Day</th>
';

// As many columns as there are slots
for($i = 1; $i <= $columns; $i++) {
    $html .= '
        <th>Working hours '.$i.'</th>
    ';
}

$html .= '
            </tr>
        </thead>
        <tbody>
';

// Loop through days...
foreach($repacked as $day=>$times) {
    $html .= '
            <tr>
                <td>'.ucfirst($day).'</td>
    ';

    // ... then through specific opening times
    foreach($times as $type=>$time) {
        // We've already picked this up during one of
        // the previous loop passes, we don't need it now
        if($type === "closing_time") {
            continue;
        }

        // Skip days with no set time - generate $columns number of cells
        if(!$time[0]) {
            $html .= str_repeat('<td></td>'.PHP_EOL,$columns);
            continue;
        }

        // With the outline of the repacked array given in 
        // lines 72-81, $time[0][0] is, in the first run through
        // the loop:
        /*
            $repacked
                $day (e.g. Monday)
                    $type (e.g. opening_time)
                        $time (a nested array, e.g. [ [10:00 am, 6:30 pm] ])
                            $time[0] ( first element of the nested array, e.g. [10:00 am, 6:30 pm] )
                                $time[0][1] (first time, e.g. 10:00 am)
        */

        // Check the slots, and generate columns
        $html .= renderSlots($columns,$repacked,$day,$time);
        
    }

    $html .= '
            </tr>
    ';
}

$html .= '
        </tbody>
    </table>
';

echo $html;
?>

上面的代码输出(逐字、空行和全部):

    <table>
        <thead>
            <tr>
                <th>Day</th>

        <th>Working hours 1</th>
    
        <th>Working hours 2</th>
    
        <th>Working hours 3</th>
    
            </tr>
        </thead>
        <tbody>

            <tr>
                <td>Monday</td>
    
                <td>10:00 am to 6:00 pm</td>
            
                <td>6:30 pm to 10:30 pm</td>
            
                <td>some other time to some other closing time</td>
            
            </tr>
    
            <tr>
                <td>Tuesday</td>
    
                <td>12:30 pm to 7:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Wednesday</td>
    
                <td>4:30 pm to 10:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Thursday</td>
    
                <td>2:30 pm to 6:30 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Friday</td>
    
                <td>4:00 pm to 11:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Saturday</td>
    
                <td>6:00 am to 6:00 pm</td>
            
                <td></td>
            
                <td></td>
            
            </tr>
    
            <tr>
                <td>Sunday</td>
    <td></td>
<td></td>
<td></td>

            </tr>
    
        </tbody>
    </table>

测试一下这里


注释

我重新打包了初始数组,以便更轻松地循环它并生成稍后渲染的 HTML 字符串。如果您控制初始表(我在提供的代码中称为

$times
的表)的形成方式,则可以避免重新打包。

渲染的 HTML 表是一个准系统表 - 您可以在循环遍历它时提供 CSS 类,或者在包含

$html
thead
tbody
变量的开头部分提供。

此外,如果您需要设置非空(或空)表格单元格的样式,也可以使用 CSS 类来实现。

代码已根据您的评论进行了调整 - 您现在可以在白天提供 N 个工作位。


0
投票

在我看来,@FiddlingAway 的答案中有太多循环。您需要一个准备循环来计算一周所需的时间段数量。然后你需要一个嵌套循环来仅遍历开放时间数据。

当您遍历开放时间时,可以通过共享的日期键和索引访问相关的关闭时间。我将使用一种有点奇特的技术,使用扩展运算符和空合并来内爆时间范围字符串,以便在没有时间数据时返回空字符串。

代码:(演示

$slots = max(array_map('count', $times['opening_time']));
echo '<table>';
foreach ($times['opening_time'] as $day => $opens) {
    echo "<tr><td>$day</td>";
    for ($i = 0; $i < $slots; ++$i) {
        printf(
            '<td>%s</td>',
            implode(
                ' to ',
                [
                    ...(array) ($opens[$i] ?? []),
                    ...(array) ($times['closing_time'][$day][$i] ?? [])
                ]
            )
        );
    }
    echo '</tr>';
}
echo '</table>';
© www.soinside.com 2019 - 2024. All rights reserved.