Від автора: Даний урок є логічним продовженням уроку “Як зробити FAQ на сайті з використанням PHP-MySQL-jQuery”. У коментарях до зазначеного уроку надійшло прохання показати, як можна реалізувати аналогічну “штуку”, але без використання БД, а з використанням в якості сховища даних, текстові файли. Також в коментарях містилося прохання показати, як створити адміністративну частину, за допомогою якої можна було б управляти зазначеним сховищем даних.
Що ж, спробуємо реалізувати завдання попереднього уроку, використовуючи для зберігання інформації текстові файли. Заодно і навчимося основам роботи з файлами в PHP, тим більше, що поки що на сайті, ніби як, немає інформації подібного роду.
Час ролика: 47:22
Складність: середня
План уроку:
1. Підготовчий етап. Формування завдань (10:24)
2. Читаємо файл (13:32)
3. Формування масиву виведення даних (11:14)
4. Виводимо дані (11:21)
$handle = fopen(‘base.txt’, ‘r’);
Результат виконання функції ми помістили в змінну $handle. Тепер ця змінна є дескриптором відкритого файлу або, говорячи простою мовою, — вона вказує на відкритий файл і саме з нею відбувається подальша робота.
Інформацію з відкритого файлу ми будемо зчитувати порядково — саме для цього ми і поміщали пару питання-відповідь в окремий рядок. Вважати рядок із файлу нам допоможе функція fgets(). Її синтаксис:
fgets(дескриптор файлу);
Але дана функція читає лише 1 рядок. Для того, щоб прочитати наступний рядок — нам потрібно викликати її ще раз і тоді буде зчитана другий рядок. Для зчитування 3-їй рядку — необхідний повторний виклик функції і т. д. У нас поки що тільки 3 рядки, а якщо таких рядків буде 1000… Думаю, Ви вже здогадалися, що у виконанні певних повторюваних однотипних дій нам допоможуть цикли. Єдине, що нам потрібно сформулювати умова циклу. Таким буде наступне: читати рядки з файлу одну за іншою поки такі є в файлі, тобто поки не досягнуто кінець файлу.
Лічені рядки ми будемо, звичайно ж, поміщати не в змінну (змінна адже призначена для зберігання тільки 1 значення, а у нас таких значення буде стільки ж, скільки і лічених рядків), ми їх будемо розміщати в масив. Оскільки ми будемо працювати з масивами, я настійно рекомендую Вам ознайомитися з усіма уроками, де порушувалася ця тема, оскільки без розуміння принципів роботи з масивами буде складно зрозуміти і всю подальшу роботу.
Тепер ще раз повернемося до умови. Як можна дізнатися чи досягнуто кінець файлу? Тут нам допоможе функція feof(), яка перевіряє, чи досягнуто кінець файлу. Її синтаксис:
feof(дескриптор файлу);
Дана функція повертає значення TRUE (ІСТИНА), якщо досягнуто кінець файлу або FALSE (БРЕХНЯ) в будь-якому іншому випадку. Таким чином, умови ми будемо перевіряти повертає функція БРЕХНЯ, якщо повертає — означає кінець файлу не досягнуто і будемо зчитувати рядок, якщо поверне ІСТИНУ, тобто умова не виконається — припинимо считвать файл. Код буде таким:
Зверніть увагу на знак оклику перед викликом функції feof(), про його використання в PHP я вже говорив — він позначає, якщо перекласти на зрозумілу мову, частку «не». Оскільки в умові ми перевіряємо повертає функція БРЕХНЯ, ми і вказали частинку “не”, тобто, якщо прочитати умова — ми отримаємо наступне: «поки не ІСТИНА){читаємо чергову рядок}». У даному випадку «не ТАК» == БРЕХНЯ.
3. Формування масиву виведення даних
Відмінно!
Ми вважали файл порядково в масив $read. Тепер кожен елемент масиву містить 1 рядок зчитаного файлу. Але нас це не зовсім влаштовує, оскільки нам потрібні питання і відповідь в розділеному вигляді. Згадуємо, саме для цих цілей у нас в кожному рядку і передбачений роздільник. Знаючи, який саме роздільник використовується, а ми знаємо це, можна розбити рядок у нашому випадку на 2 підрядка: в одній буде питання, у другій — відповідь. Виконати сформовану завдання нам допоможе функція explode(), яка, власне, і розбиває рядок на підрядки.
Її синтаксис:
explode(“сепаратор”, разбиваемая рядок);
В якості роздільника вказується роздільник — в нашому випадку використано 2 слеша («//»). Як говорилося, можна використовувати і будь-який інший роздільник — головне, щоб він не зустрічався в частині рядка, яку ми хочемо отримати в якості підрядка.
Оскільки необхідно розбити на підрядки всі елементи масиву $read — необхідно пройтися по всім елементам масиву в циклі. Перебирати елементи циклу будемо за допомогою циклу foreach(), який існує спеціально для обходу елементів масиву. Синтаксис оператора foreach():
foreach(ім’я масиву as змінна){блок дій}
Тут ми беремо кожен конкретний елемент масиву і присвоюємо на кожній ітерації циклу його значення як раз змінної, зазначеної після ключового слова as. Ну а в блоці дій ми вже виконаємо потрібний набір дій з указаної змінної.
Тепер код:
В результаті виконання коду ми отримали масив $data, який містить ще 3 масиву (по числу рядків), в кожному з яких міститься по 2 елементи (питання-відповідь). Тепер у нас є багатовимірний масив. Залишилося вивести його значення. Зробити це можна в межах того ж циклу.
4. Виводимо дані
Для того, щоб зрозуміти що і як нам потрібно вивести, досить роздрукувати вміст масивів:
Поглянувши на структуру отриманого масиву, не складно побачити, що для того, щоб, наприклад, вивести друге питання, ми повинні звернутися до індексу 1 масиву $data і вказати індекс 0 вкладеного масиву, тобто так:
echo $data[1][0];
Щоб витягнути відповідь на це питання — звертаємося уже до другого вкладеного елементу масиву, тобто до елемента з ключем 1:
echo $data[1][1];
Тепер, якщо ми для себе простежимо структуру виведених ключів всіх пар питання-відповідь, то отримаємо наступне:
00
01
10
11
20
21
Бачимо, що другі цифри в кожній парі чергуються (0 і 1), а перші цифри кожної пари збільшуються на одиницю — від нуля до трьох. Відповідно, для виведення в кожній парі першої цифри ми організуємо лічильник поза циклу (це буде змінна $i), а в циклі будемо збільшувати його на одиницю і присвоювати його значення першим ключем масиву. Ну а другі цифри ми так і будемо виводити — чергуючи 0 і 1:
‘.$data[$i][0]. ‘