SMP all works
This commit is contained in:
681
semester-4/СмП/lb-2/Лр_2_Ситник_ПЗПІ_23_2.txt
Normal file
681
semester-4/СмП/lb-2/Лр_2_Ситник_ПЗПІ_23_2.txt
Normal file
@ -0,0 +1,681 @@
|
||||
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
|
||||
ХАРКІВСЬКИЙ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ РАДІОЕЛЕКТРОНІКИ
|
||||
|
||||
|
||||
|
||||
Кафедра Програмної інженерії
|
||||
|
||||
|
||||
|
||||
|
||||
Звіт
|
||||
з лабораторної роботи №2
|
||||
з дисципліни: «Скриптові мови програмування»
|
||||
з теми: «Продовольчий магазин «Весна»»
|
||||
|
||||
|
||||
|
||||
|
||||
Виконав: Перевірив:
|
||||
ст. гр. ПЗПІ-23-2 Старший викладач кафедри ПІ
|
||||
Ситник Є. С. Сокорчук І. П.
|
||||
|
||||
|
||||
|
||||
|
||||
Харків – 2025
|
||||
2
|
||||
2 ПРОДОВОЛЬЧИЙ МАГАЗИН «ВЕСНА»
|
||||
2.1 Історія змін
|
||||
|
||||
№ Дата Версія звіту Опис змін та виправлень
|
||||
1 03.03.2025 0.1 Створено звіт
|
||||
|
||||
2.2 Мета роботи
|
||||
|
||||
Лабораторна робота полягає у розробці консольного застосунку
|
||||
«Продовольчий магазин «Весна»» засобами мови програмування «PHP».
|
||||
|
||||
2.3 Хід роботи
|
||||
2.3.1 Архітектура програми
|
||||
|
||||
Для реалізації консольного застосунку було обрано об’єктно-орієнтований
|
||||
підхід з використанням наступних компонентів:
|
||||
|
||||
2.3.1.1 Класи та їх призначення:
|
||||
|
||||
– DB – клас для роботи з базою даних «SQLite», що забезпечує збереження
|
||||
даних про товари, кошик користувача та налаштування профілю;
|
||||
– App – основний клас застосунку, що реалізує логіку роботи програми та
|
||||
взаємодію з користувачем;
|
||||
– DbException та AppException – класи винятків для обробки помилок.
|
||||
|
||||
2.3.1.2 Enum State:
|
||||
|
||||
Для управління станами програми використовується перелічення «State» з
|
||||
наступними значеннями:
|
||||
– Hello – привітальний екран;
|
||||
– Menu – головне меню;
|
||||
– Items – вибір товарів;
|
||||
– Checkout – формування рахунку;
|
||||
– Settings – налаштування профілю;
|
||||
– Exit – вихід з програми.
|
||||
3
|
||||
2.3.2 Структура бази даних
|
||||
|
||||
Програма використовує базу даних SQLite з трьома таблицями:
|
||||
– settings – зберігає інформацію про користувача (ім’я та вік);
|
||||
– items – містить каталог товарів з їх назвами та цінами;
|
||||
– cart – зберігає товари, додані до кошика, з їх кількістю.
|
||||
|
||||
2.3.3 Основний функціонал
|
||||
|
||||
2.3.3.1 Головне меню:
|
||||
|
||||
Програма відображає заголовок магазину та пропонує користувачу чотири
|
||||
основні опції:
|
||||
– вибір товарів для покупки;
|
||||
– перегляд підсумкового рахунку;
|
||||
– налаштування профілю користувача;
|
||||
– вихід з програми.
|
||||
|
||||
2.3.3.2 Вибір товарів:
|
||||
|
||||
При виборі першого пункту меню користувач потрапляє в режим покупки
|
||||
товарів, де:
|
||||
– відображається список доступних товарів з цінами;
|
||||
– можна вибрати товар за номером та вказати кількість;
|
||||
– товари додаються до кошика;
|
||||
– при введенні кількості «0» товар видаляється з кошика;
|
||||
– реалізована валідація введених даних.
|
||||
|
||||
2.3.3.3 Підсумковий рахунок:
|
||||
|
||||
Другий пункт меню формує детальний рахунок з інформацією про:
|
||||
– номер, назву та ціну кожного товару;
|
||||
– кількість товару в кошику;
|
||||
– загальну вартість кожного товару;
|
||||
– підсумкову суму до сплати.
|
||||
4
|
||||
2.3.3.4 Налаштування профілю:
|
||||
|
||||
Третій пункт дозволяє користувачу вказати своє ім’я та вік з валідацією:
|
||||
– ім’я повинно містити хоча б одну літеру;
|
||||
– вік повинен бути в діапазоні від 7 до 150 років.
|
||||
|
||||
2.3.4 Технічні деталі
|
||||
|
||||
Програма написана з дотриманням сучасних стандартів «PHP»:
|
||||
– використання строгої типізації;
|
||||
– документування методів за допомогою «PHPDoc»;
|
||||
– дотримання принципів «SOLID»;
|
||||
– розділення логіки на окремі методи для кращої читабельності.
|
||||
|
||||
2.4 Висновки
|
||||
|
||||
Під час даної лабораторної роботи я вивчив основні принципи роботи з «PHP»
|
||||
для написання консольних програм. Зокрема, було освоєно:
|
||||
– створення об’єктно-орієнтованих консольних застосунків на «PHP»;
|
||||
– роботу з базою даних «SQLite» через «PDO»;
|
||||
– обробку користувацького вводу та валідацію даних;
|
||||
– використання перелічень («enum») для управління станами програми;
|
||||
– реалізацію системи обробки винятків;
|
||||
– форматування виводу в консолі для створення зручного інтерфейсу.
|
||||
Програмне забезпечення, реалізоване протягом даної лабораторної роботи,
|
||||
повністю відповідає поставленим вимогам та забезпечує всі необхідні функції для
|
||||
роботи з продовольчим магазином. Застосунок має зручний інтерфейс, надійну
|
||||
систему валідації даних та ефективно працює з базою даних для збереження
|
||||
інформації про товари та користувача.
|
||||
5
|
||||
ДОДАТОК А
|
||||
Відеозапис
|
||||
|
||||
Відеозапис презентації результатів лабораторної роботи:
|
||||
https://youtu.be/CMGeL1OdyvI
|
||||
|
||||
Хронологічний опис відеозапису:
|
||||
00:00 – Вступ та опис завдання
|
||||
00:19 – Архітектура програми
|
||||
00:39 – Робота з базою даних
|
||||
01:43 – Реалізація станів програми
|
||||
02:17 – Формування списку товарів
|
||||
03:13 – Додавання товарів до кошика
|
||||
04:15 – Робота з кошиком
|
||||
05:10 – Налаштування профілю користувача
|
||||
05:38 – Демонстрація роботи програми
|
||||
6
|
||||
ДОДАТОК Б
|
||||
Програмний код
|
||||
|
||||
Б.1 Скрипт з реалізацією програми
|
||||
|
||||
GitHub репозиторій:
|
||||
https://github.com/NureSytnykYehor/smp-pzpi-23-2-sytnyk-yehor/blob/main/Lab2/smp-pzpi-23-2-sytnyk-yehor-lab2/smp-pzpi-23-2-sytnyk-yehor-lab2-code
|
||||
|
||||
1 #!/usr/bin/php
|
||||
2
|
||||
3 <?php
|
||||
4
|
||||
5 class DbException extends Exception {}
|
||||
6 class AppException extends Exception {}
|
||||
7
|
||||
8 enum State
|
||||
9 {
|
||||
10 case Hello;
|
||||
11 case Menu;
|
||||
12 case Items;
|
||||
13 case Checkout;
|
||||
14 case Settins;
|
||||
15 case Exit;
|
||||
16 }
|
||||
17
|
||||
18 class DB
|
||||
19 {
|
||||
20 private $pdo;
|
||||
21
|
||||
22 /**
|
||||
23 * Initializes database
|
||||
24 *
|
||||
25 * @param string $db_path
|
||||
26 * @throws DbException If there's a database error.
|
||||
27 */
|
||||
28 public function __construct($db_path)
|
||||
29 {
|
||||
30 try {
|
||||
31 $this->pdo = new PDO("sqlite:" . $db_path);
|
||||
32 $this->pdo->setAttribute(PDO::ATTR_ERRMODE,
|
||||
PDO::ERRMODE_EXCEPTION);
|
||||
33 } catch (PDOException $e) {
|
||||
34 throw new DbException("Connection to DB failed.\nCaused
|
||||
by: " . $e->getMessage());
|
||||
35 }
|
||||
36
|
||||
37 try {
|
||||
38 $this->pdo->exec("
|
||||
39 CREATE TABLE IF NOT EXISTS settings (
|
||||
40 name TEXT,
|
||||
41 age TEXT
|
||||
7
|
||||
|
||||
42 );
|
||||
43 ");
|
||||
44
|
||||
45 if ($this->pdo->query("SELECT COUNT(*) FROM settings;")-
|
||||
>fetchColumn() == 0) {
|
||||
46 $this->pdo->exec("INSERT INTO settings (name, age)
|
||||
VALUES ('user', 0);");
|
||||
47 }
|
||||
48 } catch (PDOException $e) {
|
||||
49 throw new DbException("Error initialising settings table.
|
||||
\nCaused by: " . $e->getMessage());
|
||||
50 }
|
||||
51
|
||||
52 try {
|
||||
53 $this->pdo->exec("
|
||||
54 CREATE TABLE IF NOT EXISTS items (
|
||||
55 id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
56 name TEXT NOT NULL,
|
||||
57 price REAL NOT NULL
|
||||
58 );
|
||||
59 ");
|
||||
60
|
||||
61 if ($this->pdo->query("SELECT COUNT(id) FROM items;")-
|
||||
>fetchColumn() == 0) {
|
||||
62 $this->pdo->exec("
|
||||
63 INSERT INTO items (name, price) VALUES ('Молоко
|
||||
пастеризоване', 12);
|
||||
64 INSERT INTO items (name, price) VALUES ('Хліб
|
||||
чорний', 9);
|
||||
65 INSERT INTO items (name, price) VALUES ('Сир
|
||||
білий', 21);
|
||||
66 INSERT INTO items (name, price) VALUES ('Сметана
|
||||
20%', 25);
|
||||
67 INSERT INTO items (name, price) VALUES ('Кефір
|
||||
1%', 19);
|
||||
68 INSERT INTO items (name, price) VALUES ('Вода
|
||||
газована', 18);
|
||||
69 INSERT INTO items (name, price) VALUES ('Печиво
|
||||
\"Весна\"', 14);
|
||||
70 ");
|
||||
71 }
|
||||
72 } catch (PDOException $e) {
|
||||
73 throw new DbException("Error initialising items table.
|
||||
\nCaused by: " . $e->getMessage());
|
||||
74 }
|
||||
75
|
||||
76 try {
|
||||
77 $this->pdo->exec("
|
||||
78 CREATE TABLE IF NOT EXISTS cart (
|
||||
79 id INTEGER NOT NULL UNIQUE,
|
||||
80 count INTEGER NOT NULL,
|
||||
81 FOREIGN KEY(id) REFERENCES item(id)
|
||||
82 );
|
||||
83 ");
|
||||
84 } catch (PDOException $e) {
|
||||
8
|
||||
|
||||
85 throw new DbException("Error initialising cart table.
|
||||
\nCaused by: " . $e->getMessage());
|
||||
86 }
|
||||
87 }
|
||||
88
|
||||
89 /**
|
||||
90 * Updates user information in the database
|
||||
91 *
|
||||
92 * @param string $name
|
||||
93 * @param int $age
|
||||
94 * @return void
|
||||
95 * @throws DbException If there's a database error.
|
||||
96 */
|
||||
97 public function update_user($name, $age): void
|
||||
98 {
|
||||
99 try {
|
||||
100 $stmt = $this->pdo->prepare("UPDATE settings SET name
|
||||
= :name, age = :age;");
|
||||
101
|
||||
102 $stmt->bindParam(':name', $name, PDO::PARAM_STR);
|
||||
103 $stmt->bindParam(':age', $age, PDO::PARAM_INT);
|
||||
104
|
||||
105 $stmt->execute();
|
||||
106 } catch (PDOException $e) {
|
||||
107 throw new DbException("Error updating user info.\nCaused
|
||||
by: " . $e->getMessage());
|
||||
108 }
|
||||
109 }
|
||||
110
|
||||
111 /**
|
||||
112 * Fetches all items from the database.
|
||||
113 *
|
||||
114 * @return array[]
|
||||
115 * @throws DbException If there's a database error.
|
||||
116 */
|
||||
117 public function get_items(): array
|
||||
118 {
|
||||
119 try {
|
||||
120 $stmt = $this->pdo->query("SELECT id, name, price FROM
|
||||
items ORDER BY id;");
|
||||
121 return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
122 } catch (PDOException $e) {
|
||||
123 throw new DbException("Error retrieving data from the
|
||||
items table.\nCaused by: " . $e->getMessage());
|
||||
124 }
|
||||
125 }
|
||||
126
|
||||
127 /**
|
||||
128 * Fetches all items in the cart from the database without price
|
||||
info.
|
||||
129 *
|
||||
130 * @return array[]
|
||||
131 * @throws DbException If there's a database error.
|
||||
132 */
|
||||
133 public function get_cart_no_price(): array
|
||||
134 {
|
||||
9
|
||||
|
||||
135 try {
|
||||
136 $stmt = $this->pdo->query(
|
||||
137 "SELECT name, count FROM cart
|
||||
138 INNER JOIN items ON cart.id = items.id
|
||||
139 ORDER BY cart.id;"
|
||||
140 );
|
||||
141 return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
142 } catch (PDOException $e) {
|
||||
143 throw new DbException("Error inserting init data in the
|
||||
items table.\nCaused by: " . $e->getMessage());
|
||||
144 }
|
||||
145 }
|
||||
146
|
||||
147 /**
|
||||
148 * Fetches all items in the cart from the database.
|
||||
149 *
|
||||
150 * @return array[]
|
||||
151 * @throws DbException If there's a database error.
|
||||
152 */
|
||||
153 public function get_cart(): array
|
||||
154 {
|
||||
155 try {
|
||||
156 $stmt = $this->pdo->query(
|
||||
157 "SELECT
|
||||
158 cart.id, name, price, count, price*count as
|
||||
total_price
|
||||
159 FROM cart
|
||||
160 INNER JOIN items ON cart.id = items.id
|
||||
161 ORDER BY cart.id;"
|
||||
162 );
|
||||
163 return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
164 } catch (PDOException $e) {
|
||||
165 throw new DbException("Error inserting init data in the
|
||||
items table.\nCaused by: " . $e->getMessage());
|
||||
166 }
|
||||
167 }
|
||||
168
|
||||
169 /**
|
||||
170 * Add item to the cart
|
||||
171 *
|
||||
172 * @param int $id
|
||||
173 * @param int $count
|
||||
174 *
|
||||
175 * @return bool
|
||||
176 * @throws DbException If there's a database error.
|
||||
177 */
|
||||
178 public function add_to_cart($id, $count): bool
|
||||
179 {
|
||||
180 try {
|
||||
181 $stmt = $this->pdo->prepare(
|
||||
182 "INSERT INTO cart
|
||||
183 (id, count)
|
||||
184 VALUES
|
||||
185 (:id, :count)
|
||||
186 ON CONFLICT(id)
|
||||
187 DO UPDATE SET
|
||||
10
|
||||
|
||||
188 count = :count
|
||||
189 WHERE id = :id;"
|
||||
190 );
|
||||
191 return $stmt->execute(['id' => $id, 'count' => $count]);
|
||||
192 } catch (PDOException $e) {
|
||||
193 throw new DbException("Error adding item to the cart.
|
||||
\nCaused by: " . $e->getMessage());
|
||||
194 }
|
||||
195 }
|
||||
196
|
||||
197 /**
|
||||
198 * Remove an item from the cart
|
||||
199 *
|
||||
200 * @param int $id
|
||||
201 *
|
||||
202 * @return bool
|
||||
203 * @throws DbException If there's a database error.
|
||||
204 */
|
||||
205 public function remove_from_cart($id): bool
|
||||
206 {
|
||||
207 try {
|
||||
208 $stmt = $this->pdo->prepare("DELETE FROM cart WHERE id
|
||||
= :id");
|
||||
209 return $stmt->execute(['id' => $id]);
|
||||
210 } catch (PDOException $e) {
|
||||
211 throw new DbException("Error removimg item from the cart.
|
||||
\nCaused by: " . $e->getMessage());
|
||||
212 }
|
||||
213 }
|
||||
214 }
|
||||
215
|
||||
216 class App
|
||||
217 {
|
||||
218 private $db;
|
||||
219 private $state;
|
||||
220
|
||||
221 private $menu_ops = <<<'END'
|
||||
222 1 Вибрати товари
|
||||
223 2 Отримати підсумковий рахунок
|
||||
224 3 Налаштувати свій профіль
|
||||
225 0 Вийти з програми
|
||||
226 END;
|
||||
227 private $hello = <<<'END'
|
||||
228 ################################
|
||||
229 # ПРОДОВОЛЬЧИЙ МАГАЗИН "ВЕСНА" #
|
||||
230 ################################
|
||||
231 END;
|
||||
232
|
||||
233
|
||||
234 /**
|
||||
235 * @param string $db_path
|
||||
236 */
|
||||
237 public function __construct($db_path)
|
||||
238 {
|
||||
239 try {
|
||||
240 $this->db = new DB($db_path);
|
||||
11
|
||||
|
||||
241 $this->state = State::Hello;
|
||||
242 } catch (DbException $e) {
|
||||
243 throw new AppException("Error initializing app.\nCaused
|
||||
by: " . $e);
|
||||
244 }
|
||||
245 }
|
||||
246
|
||||
247 public function poll(): void
|
||||
248 {
|
||||
249 while ($this->state != State::Exit) {
|
||||
250 switch ($this->state) {
|
||||
251 case State::Hello:
|
||||
252 $this->hello();
|
||||
253 break;
|
||||
254 case State::Menu:
|
||||
255 $this->menu();
|
||||
256 break;
|
||||
257 case State::Items:
|
||||
258 $this->items();
|
||||
259 break;
|
||||
260 case State::Checkout:
|
||||
261 $this->checkout();
|
||||
262 break;
|
||||
263 case State::Settins:
|
||||
264 $this->settings();
|
||||
265 break;
|
||||
266
|
||||
267 default:
|
||||
268 break;
|
||||
269 }
|
||||
270 }
|
||||
271 }
|
||||
272
|
||||
273 private function menu(): void
|
||||
274 {
|
||||
275 echo "\n";
|
||||
276 echo "$this->menu_ops\n";
|
||||
277
|
||||
278 $op = readline('Введіть команду: ');
|
||||
279 switch ($op) {
|
||||
280 case '1':
|
||||
281 $this->state = State::Items;
|
||||
282 break;
|
||||
283 case '2':
|
||||
284 $this->state = State::Checkout;
|
||||
285 break;
|
||||
286 case '3':
|
||||
287 $this->state = State::Settins;
|
||||
288 break;
|
||||
289 case '0':
|
||||
290 $this->state = State::Exit;
|
||||
291 break;
|
||||
292
|
||||
293 default:
|
||||
294 echo "ПОМИЛКА! Введіть правильну команду\n";
|
||||
295 break;
|
||||
12
|
||||
|
||||
296 }
|
||||
297
|
||||
298 echo "\n";
|
||||
299 }
|
||||
300 private function hello(): void
|
||||
301 {
|
||||
302 echo "$this->hello\n";
|
||||
303 $this->state = State::Menu;
|
||||
304 }
|
||||
305 private function items(): void
|
||||
306 {
|
||||
307 $items = $this->db->get_items();
|
||||
308 array_unshift($items, ['id' => "№", 'name' => "НАЗВА", 'price'
|
||||
=> "ЦІНА"]);
|
||||
309 array_push($items, ['id' => " ", 'name' => "-----------",
|
||||
'price' => ""]);
|
||||
310 array_push($items, ['id' => "0", 'name' => "ПОВЕРНУТИСЯ",
|
||||
'price' => ""]);
|
||||
311 $columns = $this->count_columns($items);
|
||||
312
|
||||
313 while (true) {
|
||||
314 $this->print_lits($items, $columns);
|
||||
315
|
||||
316 $id = readline("Виберіть товар: ");
|
||||
317
|
||||
318 if ($id == '0') {
|
||||
319 break;
|
||||
320 }
|
||||
321
|
||||
322 echo "\n";
|
||||
323
|
||||
324 $selected = null;
|
||||
325 foreach ($items as $item) {
|
||||
326 if ($item['id'] === (int)$id)
|
||||
327 $selected = $item;
|
||||
328 }
|
||||
329
|
||||
330 if ($selected == null) {
|
||||
331 echo "ПОМИЛКА! ВКАЗАНО НЕПРАВИЛЬНИЙ НОМЕР ТОВАРУ\n";
|
||||
332 continue;
|
||||
333 }
|
||||
334
|
||||
335 echo "Вибрано: {$selected['name']}\n";
|
||||
336
|
||||
337 $count = (int)readline("Введіть кількість, штук: ");
|
||||
338
|
||||
339 if ($count > 100) {
|
||||
340 echo "ПОМИЛКА! Не можна додати більше 100 одиниць
|
||||
товару в кошик\n";
|
||||
341 continue;
|
||||
342 }
|
||||
343
|
||||
344 if ($count < 0) {
|
||||
345 echo "ПОМИЛКА! Кількість не може бути від'ємною\n";
|
||||
346 continue;
|
||||
347 }
|
||||
13
|
||||
|
||||
348
|
||||
349 if ($count == 0) {
|
||||
350 echo "ВИДАЛЯЮ З КОШИКА\n";
|
||||
351 $this->db->remove_from_cart($id);
|
||||
352 } else {
|
||||
353 $this->db->add_to_cart($id, $count);
|
||||
354 }
|
||||
355
|
||||
356 $cart = $this->db->get_cart_no_price();
|
||||
357 if (count($cart) == 0) {
|
||||
358 echo "КОШИК ПОРОЖНІЙ\n";
|
||||
359 } else {
|
||||
360 echo "\nУ КОШИКУ:\n";
|
||||
361 array_unshift($cart, ['name' => "НАЗВА", 'count' =>
|
||||
"КІЛЬКІСТЬ"]);
|
||||
362 $cart_columns = $this->count_columns($cart);
|
||||
363 $this->print_lits($cart, $cart_columns);
|
||||
364 echo "\n";
|
||||
365 }
|
||||
366 }
|
||||
367
|
||||
368 $this->state = State::Menu;
|
||||
369 }
|
||||
370 private function checkout(): void
|
||||
371 {
|
||||
372 $cart = $this->db->get_cart();
|
||||
373 if (count($cart) == 0) {
|
||||
374 echo "КОШИК ПОРОЖНІЙ\n";
|
||||
375 $this->state = State::Menu;
|
||||
376 return;
|
||||
377 } else {
|
||||
378 echo "У КОШИКУ:\n";
|
||||
379 array_unshift($cart, ['id' => "№", 'name' => "НАЗВА",
|
||||
'price' => "ЦІНА", 'count' => "КІЛЬКІСТЬ", 'total_price' =>
|
||||
"ВАРТІСТЬ"]);
|
||||
380 $cart_columns = $this->count_columns($cart);
|
||||
381 $this->print_lits($cart, $cart_columns);
|
||||
382 }
|
||||
383
|
||||
384 $total_price = array_reduce($cart, function ($carry, $item) {
|
||||
385 return $carry + (int)$item['total_price'];
|
||||
386 }, 0);
|
||||
387 echo "РАЗОМ ДО СПЛАТИ: {$total_price}\n";
|
||||
388
|
||||
389 $this->state = State::Menu;
|
||||
390 }
|
||||
391 private function settings(): void
|
||||
392 {
|
||||
393 while (true) {
|
||||
394 $name = readline("Ваше ім'я: ");
|
||||
395 if ($name !== "" && preg_match("/[a-zA-Z]+/", $name))
|
||||
396 break;
|
||||
397 }
|
||||
398
|
||||
399 while (true) {
|
||||
400 $age = readline("Ваш вік: ");
|
||||
14
|
||||
|
||||
401
|
||||
402 if (!filter_var($age, FILTER_VALIDATE_INT)) {
|
||||
403 echo "ПОМИЛКА! Вік користувача потрібно вказати
|
||||
числом\n\n";
|
||||
404 continue;
|
||||
405 }
|
||||
406
|
||||
407 if ($age < 7 || $age > 150) {
|
||||
408 echo "ПОМИЛКА! Користувач повинен мати вік від 7 та до
|
||||
150 років\n\n";
|
||||
409 continue;
|
||||
410 }
|
||||
411
|
||||
412 break;
|
||||
413 }
|
||||
414
|
||||
415 echo "\n";
|
||||
416
|
||||
417 $this->db->update_user($name, $age);
|
||||
418
|
||||
419 $this->state = State::Menu;
|
||||
420 }
|
||||
421
|
||||
422 /**
|
||||
423 * @param array<array> $items
|
||||
424 * @return array<int>
|
||||
425 */
|
||||
426 private function count_columns($items): array
|
||||
427 {
|
||||
428 $columns = [];
|
||||
429 foreach ($items as $item) {
|
||||
430 foreach ($item as $field => $value) {
|
||||
431 if (!key_exists($field, $columns))
|
||||
432 $columns[$field] = mb_strlen($value);
|
||||
433 else
|
||||
434 $columns[$field] = max(mb_strlen($value),
|
||||
$columns[$field]);
|
||||
435 }
|
||||
436 }
|
||||
437
|
||||
438 return $columns;
|
||||
439 }
|
||||
440 /**
|
||||
441 * @param array $element
|
||||
442 * @param array<int> $columns
|
||||
443 */
|
||||
444 private function pad_row($element, $columns): string
|
||||
445 {
|
||||
446 $result = [];
|
||||
447 foreach ($element as $field => $value)
|
||||
448 $result[] = mb_str_pad($value, $columns[$field], ' ',
|
||||
STR_PAD_RIGHT);
|
||||
449
|
||||
450 return implode(" ", $result);
|
||||
451 }
|
||||
452 /**
|
||||
15
|
||||
|
||||
453 * @param array<array> $items
|
||||
454 * @param array<int> $columns
|
||||
455 */
|
||||
456 private function print_lits($items, $columns): void
|
||||
457 {
|
||||
458 foreach ($items as $item)
|
||||
459 echo $this->pad_row($item, $columns) . "\n";
|
||||
460 }
|
||||
461 }
|
||||
462
|
||||
463 try {
|
||||
464 $app = new App("db.sqlite");
|
||||
465 } catch (AppException $e) {
|
||||
466 echo $e;
|
||||
467 exit(1);
|
||||
468 }
|
||||
469
|
||||
470 $app->poll();
|
||||
|
Reference in New Issue
Block a user