[Из песочницы] Простой PHP генератор сложных HTML таблиц
Всем привет. Хочу поделиться свеженаписанным генератором HTML таблиц.Участились случаи сбора различной статистики и компоновки ее в сложные таблицы с различными групировками.

Заметив такую тенденцию решил автоматизировать рисование таблиц.
Как итог:
Избавил себя от составления слоеных циклов для вывода массива;
Получил стандартизацию структуры массивов;

Простейшая структураСобственно сам класс статичный, имеет 1 public метод, который принимает 2 параметра:
Table: write ($data, $tableInfo = false);
$data — сам массив, который предстоит напечатать
$tableInfo (опционально) — массив настроек таблицы
Массив $data имеет следующую структуру: 
Array
(
[0] => Array // 1 строка
(
[0] => Cell_00 // 1 ячейка 1 строки
[1] => Cell_01 // 2 ячейка 1 строки
[2] => Cell_02 // 3 ячейка 1 строки
)
[1] => Array // 2 строка
(
[0] => Cell_10 // 1 ячейка
[1] => Cell_11 // 2 ячейка
[2] => Cell_12 // 3 ячейка
)
);
for ($i=0;$i<5;$i++)
for($j=0;$j<5;$j++)
$matrix[$i][$j] = $i.$j;
Вложенные массивы
Но это примеры простейших матриц. Главной особенностью класса является автоматический подсчет rowspan и группировка данных.Если вместо строки данных(ячейки) вставить аналогичный массив, то все данные этого подмассива будут помещены в строку родителя:

Код Array ( [0] => Array ( [0] => Cell_00 [1] => Cell_01 [2] => Cell_02 )
[1] => Array ( [0] => Cell_10 [1] => Cell_11 [2] => Array ( [0] => Array ( [0] => Cell_120 )
[1] => Array
(
[0] => Cell_121
)
)
)
)
Чуть глубже:
Код
Array
(
[0] => Array
(
[0] => Cell_00
[1] => Cell_01
[2] => Cell_02
)
[1] => Array
(
[0] => Cell_10
[1] => Array
(
[0] => Array
(
[0] => Cell_110
[1] => Array
(
[0] => Array
(
[0] => Cell_1100
)
[1] => Array
(
[0] => Cell_1101
)
)
)
[1] => Array
(
[0] => Cell_111
[1] => Cell_112
)
)
)
)
Кастомизация
Итак, класс умеет автоматически рисовать сложные таблицы и подсчитывать rowspan’ы. Теперь перейдем к ручной настройке таблицы.Массив $data может содержать подмассив ['tableInfo'] — в нем можно указывать различные настройки, в зависимости от его ('tableInfo') расположения.Он может находиться:
В корне массива, при перечислении строк
Пример
Array
(
[0] => Array (…)
[1] => Array (…)
…
[n] => Array (…)
[tableInfo] => Array (…)
)
'tableInfo' расположенный в корне массива позволяет задать общие настройки и параметры для всей таблицы:
Array
(
[rowspan] => false //Отключить автоматическую группировку. Глобальное правило для всей таблицы.
[cols] => Array //Массив колонок
(
[0] => Array
(
[title] => ФИО //title указывает заголовки колонок (выводятся в th).
[key] => name //key указывает какие и в каком порядке выводить ячейки.
)
[1] => Array //title и key независимы друг от друга (//в массиве cols можно задать только title, можно только key [title] => Телефон //Но если решили указывать оба правила, то указывайте их попарно для каждой колонки, [key] => tel //иначе получите нежелательный результат )
)
//Ряд HTML атрибутов для таблицы:
[id] => tableId
[class] => tableClass
[style] => color:#000;
[args] => align=left width=80% //В args можно указывать любые атрибуты, будут переданы без изменений.
)
Этот же массив можно передать вторым параметром методу:
Table: write ($data, $tableInfo = false);
Если используются оба способа одновременно (isset ($data['tableInfo'] && isset ($tableInfo)), то в спорных случаях приоритет отдается правилам из второго массива $tableInfo.
array_replace_recursive ($data['tableInfo'], $tableInfo);
Пример использования title
Код
Array
(
[0] => Array
(
[0] => Cell_00
[1] => Cell_01
[2] => Cell_02
)
[1] => Array
(
[0] => Cell_10
[1] => Cell_11
[2] => Cell_12
)
[tableInfo] => Array
(
[cols] => Array
(
[0] => Array
(
[title] => Title 1
)
[1] => Array
(
[title] => Title 2
)
[2] => Array
(
[title] => Title 3
)
)
)
)
Пример использования key
Код
Array
(
[0] => Array
(
[0] => Cell_00
[1] => Cell_01
[2] => Cell_02
)
[1] => Array
(
[0] => Cell_10
[1] => Cell_11
[2] => Cell_12
[3] => Cell_13 //Будет проигнорирован, т.к. не указан в key
)
[tableInfo] => Array
(
[cols] => Array
(
[0] => Array
(
[key] => 2
)
[1] => Array
(
[key] => 0
)
[2] => Array
(
[key] => 1
)
)
)
)
Код
$exmpl3 = array (
'tableInfo' => array (
'cols' => array (
0 => array ('key' => 'cell0'),
1 => array ('key' => 'cell1'),
2 => array ('key' => 'cell2'),
)
),
0 => array (
'cell0' => 'Cell_00',
'cell2' => 'Cell_02',
'cell1' => 'Cell_01',
),
1 => array (
'cell0' => 'Cell_10',
'sub' => array (
0 => array (
'cell1' => 'Cell_110',
'sub' => array (
0 => array (
'cell2' => 'Cell_1100',
),
1 => array (
'cell0' => 'asdasd_10', //Не будут выведены, т.к. при выводе подмассива
'cell1' => 'asdasd_110',//учитываются только неиспользованные ключи
'cell2' => 'Cell_1101'
)
)
),
'sub' => array ('cell1' => 'Cell_111', 'cell2' => 'Cell_112'),
)
)
);
Здесь стоит упомянуть, что если key вообще не используются, то массив выводимых ключей заполняется всеми ключами ячеек (не подмассивов), которые находятся в этой строке. Например в этом случае: Код
$exmpl = array (
0 => array (
0 => 'Cell_00',
1 => 'Cell_01',
2 => 'Cell_02',
),
1 => array (
0 => 'Cell_10',
1 => 'Cell_11',
2 => 'Cell_12',
),
);
Для обоих строчек массив $colKeys (массив выводимых ячеек) будет выглядеть вот так:
$colKeys = array (0, 1, 2);
В любом массиве ячеек (на любом уровне)
Пример
Array
(
[0] => Array (
[qwe] => йцу
[asd] => фыв
[tableInfo] => Array (…)
)
[1] => Array (…)
…
)
Array
(
[0] => Array (
[qwe] => йцу
[asd] => фыв
[zxc] => Array (
[0] => Array (
[jkl] => олд
[tableInfo] => Array (…)
)
[1] => Array ()
)
)
[1] => Array (…)
…
)
'tableInfo' расположенный в массиве ячеек, может содержать настройки для строки, в которой он находится и/или настройки для каждой отдельной ячейки:
'tableInfo' => array (
'rowspan' => false, //Запретить подсчет rowspan для данной строки
'rowspan' => true, //Разрешить подсчет rowspan для данной строки
'rowspan' => 5, //Указать точное значение rowspan для данной строки
'keys' => array (//Правила по модификации масива выводимых ячеек
'delete' => 'all', //Удалить все ключи выводимых ячеек
'delete' => array ('cell2'), //Удалить некоторые ключи (тут 'cell2')
'add' => array ('cell3'), //Добавить в конец несколько ключей (тут 'cell3')
'forwarding' => array (//Замена одного ключа на другой. Можно указать несколько правил
0 => array (
'src' => 'cell1', //В этом примере вместо ячейки cell1
'dst' => 'cell2' //Будет выведена ячейка cell2
),
), //Эти правила действуют, даже если вы не указывали явно список ключей для таблицы
), //т.к. в этом случае массив выводимых ячеек будет содержать все ячейки строки
'cells' => array (//Правила для ячеек
'cell2' => array (//Массив правил для ячейки 'cell2'
'rowspan' => false, //Отключить
'rowspan' => true, //Включить
'rowspan' => 5, //Указать точное значение
'colspan' => 6, //Указать ТОЛЬКО точное значение
//Ряд HTML атрибутов для ячейки:
'id' => 'cellId',
'class' => 'cellClass',
'style' => 'color:#000;',
'args' => 'align=left width=80%'
)
),
//Ряд HTML атрибутов для строки:
'id' => 'rowId',
'class' => 'rowClass',
'style' => 'color:#000;',
'args' => 'align=left width=80%'
);
Приоритеты rowspan
Правило для ячейки (самое главное правило);
Правило для строки;
Правило для таблицы;
По умолчанию rowspan считается всегда, если присутствует подмассив.
Ну, вот и все. Некоторые моменты решил не рассматривать подробно, если будут вопросы — распишу.Скачать класс Table
