2012-06-30 3 views
2

Я делаю HTML-таблицу на основе определенной информации в моей базе данных MySQL. Таблицы мне нужно из базы данных хранятся данные по строкам (RowId, rowname), колонны (columnid, имя_столбца) и данные ячейки. В таблице, которая связывает идентификаторы из строк и столбцов вместе (CellID, RowId, columnid, somedata). таблица выглядит следующим образом:PHP: Создание большой HTML-таблицы эффективно

__________| column1 | column2 | column3 | ... 
    row1 | somedata | somedata |   | 
----------|----------|----------|----------|----- 
    row2 | somedata |   | somedata | 
----------|----------|----------|----------|----- 
...  |   |   |   | 

Мой подход заключается в использовании нескольких вложенных циклов Foreach, что-то вроде этого:

$rows = new Rows();  //These objects are containers for objects 
$columns = new Columns(); //that hold some of the database data. 
$alldata = new Alldata(); //MySQL queries within these objects are irrelevant, I think. They already get the relevant data 

$count = count($alldata); 

echo "<table>"; 
echo "<tr>"; 
echo "<td>&nbsp;</td>"; 

foreach ($columns->getColumns() as $column) { 
    echo "<td>".$column->getColumnname()."</td>"; 
} 

echo "</tr>"; 

foreach ($rows->getRows() as $row) { 
    echo "<tr>"; 
    echo "<td>".$row->getRowname()."</td>"; 

    foreach ($columns->getColumns() as $column) { 
     $last = 1; 

     foreach ($alldata->getAlldata() as $data) { 
      if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) { //If the column has data the related to the row 
       echo "<td>".$data->getSomedata()."</td>"; 
       break; 
      } 
      if ($last == $count) { //if loop couldn't find any entries, it prints an empty cell 
       echo "<td>&nbsp;<td>"; 
      } 
      $last++ 
     } 
    } 
    echo "</tr>"; 
} 
echo "</table>"; 

Bruteforcing, очевидно, что это не очень эффективный метод, когда существует несколько сотен строки данных в любой таблице в базе данных, и мне это не нравится. Любые идеи, как сделать это более эффективным? Есть ли лучший способ создать таблицу, как мне нужно?

EDIT:
Обдумывая эту проблему в течение недели, я наконец-то дал мне несколько ответов. Это было так просто!
Я сделал небольшую модификацию для моего класса Столбец. Ранее мой код прошел через все возможные записи на celldata таблица в базе данных. Теперь Столбец объект получает массив celldata где столбец соответствует, и я могу сделать сравнение, используя только эти данные.

$rows = new Rows(); 
$columns = new Columns(); 

echo "<table>"; 
echo "<tr>"; 
echo "<td>&nbsp;</td>"; 

foreach ($columns->getColumns() as $column) { 
    echo "<td>".$column->getColumnname()."</td>"; 
} 

echo "</tr>"; 

foreach ($rows->getRows() as $row) { 
    echo "<tr>"; 
    echo "<td>".$row->getRowname()."</td>"; 

    foreach ($columns->getColumns() as $column) { 
     $last = 1; 
     $count = count($column->getAlldata()); 

     foreach ($column->getAlldata() as $data) { 
      if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) { 
       echo "<td>".$data->getSomedata()."</td>"; 
       break; 
      } 
      if ($last == $count) { 
       echo "<td>&nbsp;<td>"; 
      } 
      $last++ 
     } 
    } 
    echo "</tr>"; 
} 
echo "</table>"; 

Гораздо быстрее, хотя все еще грубый, но есть меньше данных для прохождения. Конечно, теперь проблема заключается в том, что В столбцах объекты могут выполнять довольно много запросов MySQL, в зависимости от количества Столбцы есть.

+0

ли идентификаторы строк и столбцов гарантированно будет в порядке? – eggyal

+0

Очень интересный вопрос! –

+0

@eggyal строки и столбцы сортируются по их имени, поэтому нет. – RLXi

ответ

1

Если вы убедитесь, что данные, выбираемые из MySQL правильно заказать в $alldata путем объединения таблиц и указав ORDER BY условие в запросе:

SELECT data.* 
FROM  data RIGHT JOIN rows USING (rowid) RIGHT JOIN columns USING (columnid) 
ORDER BY rowname, columnname; 

Тогда вам нужно только для вывода каждой ячейки в следующем порядке:

echo '<table>'; 

echo '<thead>' 
echo '<tr>'; 
echo '<th>&nbsp;</th>'; 
foreach ($columns->getColumns() as $column) { 
    echo '<th scope="col">', htmlentities($column->getColumnname()), '</th>'; 
} 
echo '</tr>'; 
echo '</thead>'; 

echo '<tbody>'; 
$data = $alldata->getAlldata(); 
foreach ($rows->getRows() as $row) { 
    echo '<tr>'; 

    echo '<th scope="row">', htmlentities($row->getRowname()), '</th>'; 
    foreach ($columns->getColumns() as $column) { 
     $d = each($data); 
     echo '<td>', ($d ? htmlentities($d[1]->getSomedata()) : '&nbsp;'), '</td>'; 
    } 

    echo '</tr>'; 
} 
echo '</tbody>'; 

echo '</table>'; 
+0

Спасибо, я попробую это и посмотрю, что произойдет. – RLXi

+0

, если это действительно большой стол, и вы хотите попробовать небольшую оптимизацию, вы можете попробовать использовать запятую "," вместо конкатенации ". в ваших сообщениях эха. – Dharmavir

+0

Этот запрос MySQL выглядел очень неплохо. Когда я исследовал, какие объекты хранятся, были некоторые объекты с нулевыми значениями. Возможно, именно это я и искал. Однако ваш код не работает с моим. Проблема заключается в $ d = $ data-> getSomedata(). $ data - это не объект, а массив, поэтому он не может использовать эту функцию. – RLXi

0

лучший способ для решения этой проблемы было бы переписать запрос для $alldata так, что он находится в порядке, вы хотите, как eggyal предложил. Если вы не можете сделать это по какой-либо причине, вы можете выполнить итерацию через $alldata в начале и создать из него правильно проиндексированный массив. Что-то вроде этого:

$ordereddata = array(); 
foreach($alldata as $d) { 
    $ordereddata[$d->getCID()][$d->getRID()] = $d->getSomedata(); 
} 

Теперь вы можете заменить foreach($alldata) цикл с этим:

if(isset($ordereddata[$column->getID()][$row->getID()])) { 
    echo "<td>{$ordereddata[$column->getID()][$row->getID()]}</td>"; 
} else { 
    echo "<td>&nbsp;</td>"; 
} 
+0

У меня есть полный доступ к любой части кода. Я на самом деле пытался что-то подобное раньше, но это не сработало. Я получил все данные, но я не мог печатать пустые ячейки. Каждая ячейка выравнивается влево без пробелов между ними. – RLXi

Смежные вопросы