PHP Manual

Таблиця непередбачених обставин на PHP

13. 11. 2019

Таблиця непередбачених обставин зазвичай використовується для того, щоб показати взаємозв'язок між двома статистичними явищами. При розробці веб-додатку нам часто потрібно буде візуалізувати зв'язок певного явища в базі даних з часовою послідовністю, як правило, в адмініструванні.

Наприклад, у нас є таблиця замовлень, яка показує окремі продукти, і нас цікавить, як продажі певних масових продуктів пов'язані з часом.

Для цього була б корисною таблиця на кшталт наведеної нижче:

Фініки, яблука, полуниця, груші.
2019-05
2019-04
2019-03
2019-02
2019-01

Немає простого способу підготувати дані в цю форму на PHP, а отримати їх безпосередньо в цю форму безпосередньо на SQL теж не елегантно, тому що доводиться враховувати, що є динамічна кількість стовпців.

Тож потрібно з розумом підходити до проектування виводу цієї структури даних.

Серіалізація даних за допомогою ключів

При побудові таблиці я часто використовую отримання всіх записів, які задовольняють заданій умові, безпосередньо з бази даних, наприклад, інтервальних даних.

А саме:

SELECT *
FROM `order`
WHERE `inserted_date` <= '2019-05-01'
ORDER BY `inserted_date` DESC

Запит отримує всі стовпці в таблиці порядку (order), фільтруючи всі записи від початку віків до 2019-05-01, повертаючи відсортовані від найновіших до найстаріших.

За допомогою простого SQL-запиту ми отримуємо дані майже миттєво. Другою приємною особливістю є те, що індекси бази даних можуть бути ефективно використані при компіляції результатів. Однак, оскільки ми маємо дані у вигляді простого масиву, ми повинні додатково вручну серіалізувати їх у структуру даних, яка може бути перетворена в контиговану таблицю.

Оскільки таблиця непередбачених обставин описує взаємозв'язок двох або більше факторів, має сенс використовувати багатовимірний ключ. Однак, оскільки деякі дані можуть існувати не для всіх комбінацій, краще серіалізувати ключ в один рядок і зберігати дані у вигляді плоского масиву.

Дані можуть бути зібрані за один прохід циклу (змінна $selection містить вивід з бази даних):

$data = [];
foreach ($selection as $row) {
$date = date('Y-m', $row->insertedDate); // Дата рік-місяць
foreach ($row->items as $product) { // перебираємо продукти
$key = $date . '_' . $product->id;
if (isset($data[$key])) {
$data[$key]++; // існує, ми додамо інший товар
} else {
$data[$key] = 1; // не існує, ми запустимо перший продукт
}
}
}

Якби ми досліджували простішу структуру даних, внутрішній цикл не був би потрібен для перегляду продуктів. У цьому випадку весь масив даних можна було б вирішити за один цикл.

При такому підході ми отримуємо так званий плоский масив значень, який має вигляд "ключ: значення", зберігаючи при цьому двовимірну інформацію.

Тоді результатом буде, наприклад, (у травні 2019 року товар з ідентифікатором 10продано6` одиниць):

$data = [
'2019-05_10' => 6,
...
];

Виведення даних в таблицю - шаблони

Якщо у нас є дані у вигляді плоского масиву, ми можемо дуже легко відрендерити всю таблицю. Для цього нам достатньо знати поля всіх товарів, які нас цікавлять, і поля всіх дат, для яких ми хочемо побудувати таблицю.

$products = [ ... ]; // поле товару: id => name
$dates = [ ... ]; // за датою: дата => мітка
echo '<таблиця';
foreach ($products as $productId => $productName) {
echo '<tr>';
foreach ($dates as $date => $dateLabel) {
echo '<td>';
echo htmlspecialchars(
(string) ($data[$date . '_' . $productId] ?? '0')
);
echo '<td>';
}
echo '</tr> </li> <li>Примітка.';
}
echo '</table></table';

Зауважимо, що при перегляді даних він шукає конкретне входження по згинанню рядкових ключів. Такий підхід дозволяє довільно обмежувати або розширювати відображувану таблицю в залежності від того, які дані ми переглядаємо. Якщо дані відсутні, обчислюється тернарний оператор ?? та виводиться нуль.

Ми можемо створити масив доступних продуктів і дат в рамках першого циклу, який готує дані. Тоді ми будемо впевнені, що наносимо на карту лише ті дані, які дійсно існують. В даному випадку дуже важливо, щоб вивід з бази даних SQL був відсортований за датою створення, інакше при остаточному рендері таблиці рядки можуть бути перемішані.

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
3.
Status:
All systems normal.
2024