2015-07-10 34 views
0

我想知道什麼是最好的方法來分割HTML視圖和CSV導出(相同的視圖數據)的責任。我不想重複寫同一塊CSV代碼時,它幾乎是在做同樣的事情。爲HTML <table>和CSV分割職責?

下面的示例代碼,首先從數據庫中獲取數據,然後將其處理成多維數組。你可以看到我用了很多foreach來生成報告。我有重複這個CSV導出嗎?必須有DRY解決方案。

下面的示例代碼,您將如何拆分CSV和HTML的職責?

function report($campaign, $agent, $startDate, $endDate) { 

    $sql = "SELECT count(*) as total, group_name, field, field, field, FROM table some ... inner joins table .. WHERE ... group by agent"; 

    $q = mysql_query($sql) or die(mysql_error()); 

    while($row = mysql_fetch_assoc($q)) { 

     $report[ $row['group_name'] ][ $row['item'] ] ['total'] = 0; 
     $report[ $row['group_name'] ][ $row['item'] ] ['total'] += $row['total']; 
     $report[ $row['group_name'] ][ $row['item'] ] ['agent'][$row['agent']] = $row; 

     if (!array_key_exists($row['agent'], $fieldsAgent)) { 
      ..... 
     } 
    } 

    $html = "<table>"; 

    $html .= " <tr>"; 
    $html .= " <td>Group</td>"; 
    $html .= " <td>Item</td>"; 

    foreach($fieldsAgent as $agentCol => $agentTotal) { 
     $html .= "<td>$agentCol</td>"; 
    } 

    $html .= " <td>Total</td>"; 
    $html .= " </tr>"; 

    foreach ($report as $category => $items) { 

     foreach($items as $itemName => $itemData) { 

      $html .= "<tr>"; 
      $html .= " <td>" . $category . "</td>"; 
      $html .= " <td>" . $itemName . "</td>"; 

      foreach($fieldsAgent as $fieldAgentName => $totalAgentUser) { 

        $total = $itemData['agent'][ $fieldAgentName ][ 'total' ]; 
        $html .= "<td>" . $total . "</td>"; 
      } 

      $html .= " <td>" . $itemData['total'] . "</td>"; 
      $html .= "</tr>"; 
     } 
    } 

    $html .= "</table>"; 

    echo $html; 
} 
+3

乾的解決方案是您的演示文稿從您的數據邏輯分開,然後有兩個獨立的表示層(一個用於HTML,其他csv)....這是什麼MVC是關於 –

回答

1

我會做一個叫什麼之類的函數tr_or_csv()

function tr_or_csv($data = array(), $mode = 'csv') 
{ 
    $result = ''; 

    if(is_array($data) && $data) 
    { 
     $mode = (is_string($mode) ? (in_array(strtolower($mode, array('csv','tr'))) ? $mode : 'csv') : 'csv'); 

     if($mode === csv) 
     { 
      $handle = fopen('php://temp', 'r+'); 
      fputcsv($handle, $data, ','); 
      rewind($handle); 
      while (!feof($handle)) 
      { 
       $result.= fread($handle, 8192); 
      } 
      fclose($handle); 
     } 
     else 
     { 
      $result = '<tr><td>'; 
      $result.= implode('</td><td>', $data); 
      $result.= '</td></tr>'; 
     } 
    } 

    return $result; 
} 

function report($campaign, $agent, $startDate, $endDate, $mode) 
{ 
    // MySQL stuff, etc... 

    $html.= tr_or_csv(array('Group','Item','Total'), $mode); 

    // More code 
} 

report('new_campaign', 'Bob', '2015-01-01', '2015-07-10', 'tr'); 
+0

我想我理解你做的邏輯,非常有趣。你能想到另一種解決方案嗎?而不是爲循環中的每一行執行'tr_or_csv()'。如何獲取數據並返回一個函數,一個函數在html中輸出數據,一個函數用csv輸出數據。例如:'$ output [] ['column_name'] ='colum_value''那麼你可以通過接受數組或傳遞給html的csv函數格式化爲CSV? –

+0

@ I'll-Be-Back如果您瞭解我的代碼,那麼您爲什麼無法想出解決方案?你基本上必須將我所做的分成兩個功能。 – MonkeyZeus

+1

@ I'll-Be-Back除DRY之外,您還應該考慮YAGNI原則。 – MonkeyZeus