代码之家  ›  专栏  ›  技术社区  ›  TheOrdinaryGeek

Codeigniter表库句柄空/空值

  •  1
  • TheOrdinaryGeek  · 技术社区  · 6 年前

    我用的是CodeIgniter3和 table library 以便按以下格式显示某些数据;

    +---------------+---------------------+
    | id            | 102                 |
    +---------------+---------------------+
    | First Name    | Ross                |
    +---------------+---------------------+
    | Last Name     | Bing                |
    +---------------+---------------------+
    | Title         | Doctor              |
    +---------------+---------------------+
    | Timestamp     | 2019-01-18 10:17:05 |
    +---------------+---------------------+
    | Member Number |                     |
    +---------------+---------------------+
    

    一堆垃圾 $tableData 是;

    Array
    (
        [0] => Array
            (
                [id] => 102
                [firstname] => Ross
                [lastname] => Bing
                [title] => Doctor
                [timestamp] => 2019-01-18 10:17:05
                [member_no] => 
            )
    )
    

    我用来生成HTML表的PHP代码是;

    $tableData = $this->My_model->getData();
    
    $heading = array(
        'id' => 'ID',
        'firstname' => 'First Name',
        'lastname' => 'Last Name',
        'title' => 'Title',
        'timestamp' => 'Date Submitted',
        'member_no' => 'Member Number'
    );
    
    $fields = array_keys($tableData[0]);
    $rows = array();
    
    foreach($fields as $key => $field) {
        $rows[$key][0] = array(
            'data' => '<strong>' . $heading[$field] . '</strong>'
        );
        foreach($tableData as $key2 => $item) {
            $rows[$key][$key2 + 1] = $item[$field];
        }
    }
    
    foreach($rows as $row) {
        $this->table->add_row($row);
    }
    

    但是,如果一行是空的,则上面的代码可以正常工作(请参见 member_no

    • 完全隐藏表行
    • 显示 not available

    我怎样才能做到这一点?

    0 回复  |  直到 6 年前
        1
  •  2
  •   ArtisticPhoenix    6 年前

    我会这样做:

    $tableData = array (
        0 => 
        array (
            'id' => 102,
            'lastname' => 'Bing',
            'title' => 'Doctor',
            'timestamp' => '2019-01-1810:17:05',
            'member_no' => null,
            'firstname' => 'Ross', //intentionally moved to show ordering
            'foobar' => 'blah' //added for example, this will be removed by array_intersect_key
        ),
    );
    
    $heading = array(
        'id' => '<strong>ID</strong>',
        'firstname' => '<strong>First Name</strong>',
        'lastname' => '<strong>Last Name</strong>',
        'title' => '<strong>Title</strong>',
        'timestamp' => '<strong>Date Submitted</strong>',
        'member_no' => '<strong>Member Number</strong>'
    );
    
    //create a default array
    //this takes the keys from $heading, and makes an array with all the values as 'not available'
    // ['id' => 'not available','lastname' => 'not available', ... ]
    $default = array_fill_keys(array_keys($heading), 'not available');
    $rows = [];
    
    foreach($tableData as $key => $row) {
        //remove all elements with strlen of 0 (in this case 'member_no')
        $row = array_filter($row, function($item){return strlen($item);});
    
        //removes 'foobar' or anything that has a key not in $heading
        $row = array_intersect_key($row, $heading);
    
        //combine $default and $data (empty items in $row are filled in from default)
        //such as items removed by array_filter above
        //the key order will match $default, which matches $headings
        $row = array_merge($default, $row);
    
        $rows[] = $row;
    }
    
    foreach($heading as $key=>$value) {
        print_r(array_merge([['data'=>$value]], array_column($rows, $key)));
    }
    

    输出

    Array
    (
        [0] => Array
            (
                [data] => <strong>ID</strong>
            )
    
        [1] => 102
        //[2] => 108
        //...
    )
     ....
    

    Sandbox

    //...
    $default = array_fill_keys(array_keys($heading), 'not available');
    
    foreach($tableData as $key => $row) $rows[] = array_merge($default, array_intersect_key(array_filter($row, function($item){return strlen($item);}), $heading));
    
    foreach($heading as $key=>$value) print_r(array_merge([['data'=>$value]],array_column($rows, $key)));
    

    Sandbox

    我不得不猜测一下最终的结果是什么,所以我运行了你的原始代码,它给了我这个:

    Array
    (
        [0] => Array
            (
                [data] => <strong>ID</strong>
            )
    
        [1] => 102
        //[2] => 108
        //...
    )
    ....
    

    在我的代码中,你可以替换 print_r 有了这个电话 $this->table->add_row([..array data..]); . 在哪里? array data 里面的东西 打印\r

    • 关键顺序 $headings 元素会出现在 $标题 数组,无论它们在何处 $tableData . 这也允许轻松地重新排序数据,例如:您甚至可以将其映射到一个动态数组,我在CSV文件中这样做,它允许用户更改标题和列的顺序。他们甚至可以重命名标题,因为 key => value 配对工作 my_key => their_key ...
    • 中缺少数据 $表格数据 not available $default ,理论上你可以手动将其映射到不同的东西。例如:您可以通过 $default['timestamp'] = date('Y-m-d H:i:s'); 就在用 array_fill_keys .
    • 中的额外数据 中未定义 $标题
    • 而且它更容易理解(一旦你知道它是如何工作的),因为有更少的“瞬态”变量和更少的摆弄键等。。。

    基本上我所做的就是把控制权交给 $标题 数组,在原始代码中。你可以通过循环键来实现这一点( fields ),但这会让以后的事情变得更复杂 $rows[$key][$key2 + 1] . 如果以后数据发生更改(例如向数据库中添加新字段),则会出现未定义的数组索引问题。 输出的顺序取决于中的数据 $表格数据 $标题 .

    以下是原始代码中这些问题的示例:

    //for example if your data changes to this and run your original code
     $tableData = array (
     0 => 
        array (
            'id' => 102,
            'lastname' => 'Bing',
            'title' => 'Doctor',
            'timestamp' => '2019-01-1810:17:05',
            'member_no' => null,
            'firstname' => 'Ross', //intentionally moved to show ordering
            'foo' => 'bar' //added this undefined in $headings
        ),
    );
    

    您将看到此通知,并发现最后两个元素是:

     <br />
     <b>Notice</b>:  Undefined index: foo in <b>[...][...]</b> on line <b>30</b><br />
     //... all other elements ...
    
     //in orignal: displayed in the order of $tableData
     //in my code: order is based on $headings, so this would be moved to the correct location
    Array(
        [0] => Array (
             [data] => <strong>First Name</strong>
        )        
        [1] => Ross
    )
    
    //in orignal: $headings['foo'] is not defined so we have no label here
    //in my code: this element is removed and doesn't get rendered
    Array(
         [0] => Array(
               [data] => <strong></strong>
          )
    
         [1] => bar
    )
    

    Sandbox (Orignal Code)

    虽然这些事情可能永远不会引起问题,但它突出了我的观点,即基于 而不是 $表格数据 . 事情往往会发生变化,这样如果你从这个数据中添加/删除一个字段,你就不必担心它会破坏这个页面等等。。。

    数组填充键 , array_intersect_key array_merge 可以用来将一个数组的头(如上图所示)映射到另一个数组。你可以用 array_combine($headings, $row) 物理交换它们,你会得到这样的结果:

    [
         [
             '<strong>ID</strong>' => 102,
             '<strong>First Name</strong>' => 'Ross',
              //...
         ],
         [...]
    ]
    

    它适用于CSV文件(这是我发现的)和任何其他需要重新映射密钥的文件。

    不管怎样,希望对你有帮助!