通过PHP将多维数组转换为HTML表

时间:2018-12-06 16:40:26

标签: php arrays multidimensional-array html-table

假设我有一个像这样的数组:

array (
      0 =>
      array (
        'trip' => '1',
        'times' =>
        array (
          0 =>
          array (
            'order' => '1',
            'stop name' => 'Name 1',
            'stop time' => '7:03 am',
          ),
          1 =>
          array (
            'order' => '2',
            'stop name' => 'Name 2',
            'stop time' => '8:03 am',
          ),
          2 =>
          array (
            'order' => '3',
            'stop name' => 'Name 3',
            'stop time' => '9:03 am',
          ),
        ),
      ),
      1 =>
      array (
        'trip' => '2',
        'times' =>
        array (
          0 =>
          array (
            'order' => '1',
            'stop name' => 'Name 1',
            'stop time' => '10:03 am',
          ),
          1 =>
          array (
            'order' => '2',
            'stop name' => 'Name 3',
            'stop time' => '11:03 am',
          ),
        ),
      ),
      0 =>
      array (
        'trip' => '3',
        'times' =>
        array (
          0 =>
          array (
            'order' => '1',
            'stop name' => 'Name 1',
            'stop time' => '1:03 pm',
          ),
          1 =>
          array (
            'order' => '2',
            'stop name' => 'Name 2',
            'stop time' => '2:03 pm',
          ),
          2 =>
          array (
            'order' => '3',
            'stop name' => 'Name 3',
            'stop time' => '3:03 pm',
          ),
        ),
      ),
    )

但是我想通过PHP将这个数组转换成一个看起来像这样的表:

Name 1    | Name 2   | Name 3
------------------------------
7:03am    | 8:03am   | 9:03am
------------------------------
10:03am   |          | 11:03am
------------------------------
1:03pm    | 2:03pm   | 3:03pm

基本上,根据嵌套数组的数据可能存在间隙。我已经可以像没有间隙一样构造一个表,但这会产生问题,并且我基于数据库使用的数据不允许插入间隙,因此我需要知道是否有一个简单的方法。用php和array命令构建这样的表的方式,如果有值,可以记住并填充行名,如果没有,则可以传递行名。

2 个答案:

答案 0 :(得分:2)

由于您可能会有随机的间隔(带有/不带有某些名称的行程),因此您需要首先弄清所有唯一名称,并在每次行程中将其填充为空白,而不使用它们。

数据

$a = array (
  0 =>
  array (
    'trip' => '1',
    'times' =>
    array (
      0 =>
      array (
        'order' => '1',
        'stop name' => 'Name 1',
        'stop time' => '7:03 am',
      ),
      1 =>
      array (
        'order' => '2',
        'stop name' => 'Name 2',
        'stop time' => '8:03 am',
      ),
      2 =>
      array (
        'order' => '3',
        'stop name' => 'Name 3',
        'stop time' => '9:03 am',
      ),
    ),
  ),
  1 =>
  array (
    'trip' => '2',
    'times' =>
    array (
      0 =>
      array (
        'order' => '1',
        'stop name' => 'Name 1',
        'stop time' => '10:03 am',
      ),
      1 =>
      array (
        'order' => '2',
        'stop name' => 'Name 3',
        'stop time' => '11:03 am',
      ),
    ),
  ),
  2 =>
  array (
    'trip' => '3',
    'times' =>
    array (
      0 =>
      array (
        'order' => '1',
        'stop name' => 'Name 1',
        'stop time' => '1:03 pm',
      ),
      1 =>
      array (
        'order' => '2',
        'stop name' => 'Name 2',
        'stop time' => '2:03 pm',
      ),
      2 => // Fixed this to 2 instead of 0 from your example
      array (
        'order' => '3',
        'stop name' => 'Name 3',
        'stop time' => '3:03 pm',
      ),
    ),
  ),
);

代码

// Get a listing of all unique names available in this multi-dimensional array
// We need this to figure out how many gaps there may be in the data per trip
$unique_names = array();
foreach( $a as $v )
{
    foreach( $v[ 'times' ] as $v2 )
    {
        $unique_names[ $v2[ 'stop name' ] ] = $v2[ 'stop name' ];
    }
}

// Create a listing of trips and contain all available names within it even if that name did not have an entry
$trips = array();
foreach( $a as $v )
{
    // Per trip hold the stops in the same order as the $unique_names which were encountered
    $trips[ $v[ 'trip' ] ] = array();

    // Per name add a trip stop
    foreach( $unique_names as $name )
    {
        $in_trip = false;

        // Loop the available stops and check if this name is a stop
        foreach( $v[ 'times' ] as $v3 )
        {
            if( $v3[ 'stop name' ] === $name )
            {
                $trips[ $v[ 'trip' ] ][] = $v3[ 'stop time' ];
                $in_trip = true;
                break;
            }
        }

        // This name was not a stop so it will get an empty entry
        if( !$in_trip )
        {
            $trips[ $v[ 'trip' ] ][] = '';
        }
    }
}


// Show the names
echo '<table><tr>';
foreach( $unique_names as $name )
{
    echo '<td>'.$name.'</td>';
}
echo '</tr>';

// Loop the trips and output their stop times
// The stop times should be in the same order as $unique_names
foreach( $trips as $trip )
{
    echo '<tr>';
    foreach( $trip as $time )
    {
        echo '<td>'.$time.'</td>';
    }
    echo '</tr>';
}
echo '</table>';

输出

Name 1    Name 2   Name 3
7:03 am   8:03 am  9:03 am
10:03 am           11:03 am
1:03 pm   2:03 pm  3:03 pm

enter image description here

答案 1 :(得分:2)

这是另一个解决方案,但是正如MonkeyZeus所指出的那样;数组中的第一个键和最后两个键均为0。因此,使用修改后的数组。

$array = array (
          0 =>
          array (
            'trip' => '1',
            'times' =>
            array (
              0 =>
              array (
                'order' => '1',
                'stop name' => 'Name 1',
                'stop time' => '7:03 am',
              ),
              1 =>
              array (
                'order' => '2',
                'stop name' => 'Name 2',
                'stop time' => '8:03 am',
              ),
              2 =>
              array (
                'order' => '3',
                'stop name' => 'Name 3',
                'stop time' => '9:03 am',
              ),
            ),
          ),
          1 =>
          array (
            'trip' => '2',
            'times' =>
            array (
              0 =>
              array (
                'order' => '1',
                'stop name' => 'Name 1',
                'stop time' => '10:03 am',
              ),
              2 =>
              array (
                'order' => '2',
                'stop name' => 'Name 3',
                'stop time' => '11:03 am',
              ),
            ),
          ),
          2 =>
          array (
            'trip' => '3',
            'times' =>
            array (
              0 =>
              array (
                'order' => '1',
                'stop name' => 'Name 1',
                'stop time' => '1:03 pm',
              ),
              1 =>
              array (
                'order' => '2',
                'stop name' => 'Name 2',
                'stop time' => '2:03 pm',
              ),
              2 =>
              array (
                'order' => '3',
                'stop name' => 'Name 3',
                'stop time' => '3:03 pm',
              ),
            ),
          ),
        );

foreach ($array as $trow) {
            ?>
        <tr>
            <?php

            $count = 0;

            for ($i=0; $i <= count($trow['times']) ; $i++) { 
                if ($count == $i) {
                    ?>
                    <td><?= $trow['times'][$count]['stop time']; ?></td>
                    <?php
                } else {
                    ?>
                    <td></td>
                    <?php
                }
                $count++;
            }


            ?>
        </tr>
            <?php
            }