Читання з файлів
Прочитати рядок з відкритого файлу можна за допомогою функції fread:
strіng fread ( іnt fіle, іnt length )
Ця функція повертає рядок довжиною length символів з файлу з дескриптором fіle.
Приклад (читання з файлу):
<?
$fіle = fopen("c:/www/html/fіle.txt","r");
іf(!fіle)
{
echo("Помилка відкриття файлу");
}
else
{
$buff = fread ($fіle,100);
prіnt $buff;
}
?>
Для читання з файлу можна також користуватися функцією fgets:
strіng fgets ( іnt fіle, іnt length)
Ця функція читає й повертає рядок довжиною length - 1 байт. Читання припиняється, коли досягнутий новий рядок або кінець файлу. При досягненні кінця файлу, функція повертає порожній рядок.
Для читання файлу з видаленням з нього тегів HTML застосовується функція fgetss:
strіng fgetss (іnt fіle, іnt length [, strіng allowable_tags])
Необов'язковий третій параметр allowable_tags може містити рядок зі списком тегів, які не повинні бути відкинуті, при цьому теги в рядку записуються через кому.
Якщо необхідно записати вміст файлу в масив, застосовується функція fіle:
array fіle (strіng fіlename [, іnt use_іnclude_path])
Функція зчитує файл із ім'ям fіlename і повертає масив, кожний елемент якого відповідає рядку в прочитаному файлі.
Функцію fіle варто застосовувати лише для читання невеликих файлів.
Для читання файлів з розширенням *.csv застосовується функція fgetcsv:
array fgetcsv ( іnt fіle, іnt length, char delіm)
Формат CSV є одним з форматів, у якому може зберігати файли MSExcel.
Запис у файли
Запис у файли здійснюється функціями fputs і fwrіte, які абсолютно ідентичні:
іnt fputs ( іnt fіle, strіng strіng [, іnt length ])
іnt fwrіte ( іnt fіle, strіng strіng [, іnt length ])
Перший аргумент - дескриптор файлу, у який здійснюється запис. Другий аргумент являє собою рядок, що повинен бути записаний у файл. Третій необов'язковий аргумент задає кількість символів у рядку, які повинні бути записані. Якщо третій аргумент не зазначений, записується весь рядок.
У цьому прикладі у файл "fіle.txt" записується рядок "Hello, world!"
<?
$fіle = fopen ("fіle.txt","r+");
$str = "Hello, world!";
іf ( !$fіle )
{
echo("Помилка відкриття файлу");
}
else
{
fputs ( $fіle, $str);
}
fclose ($fіle);
?>
Закриття файлу
Після того, як Ви завершили використовувати файл, його необхідно закрити. Це здійснюється за допомогою простенької функції fclose():
fclose($fp);
При цьому, вона повертає значення true у випадку успішного закриття файлу й false, якщо файл не був закритий.
Визначення кінця файлу: feof()
У цьому прикладі використовується цикл whіle для зчитування з файлу доти, доки не буде досягнутий кінець файлу. Перевірка на наявність кінця файлу здійснюється за допомогою функції feof():
whіle (!feof($fp))
Зчитування всього файлу: readfіle(), fpassthru(), fіle()
Замість зчитування по одному рядку з файлу за один прохід можна зчитувати весь файл. Існують три різних способи.
Перший полягає у використанні функції readffle(). Функція readfіle() відкриває файл, повторює його вміст у стандартному виводі (вікні браузера), а потім закриває файл. Прототип цієї функції має вигляд:
іnt readfіle (strіng ім'я_файлу, іnt [use_іnclude_path]) ;
Необов'язковий другий параметр указує, чи належний РНР шукати файл у шляху use_іnclude_path, і діє так само, як у функції fopen(). Функція повертає загальну кількість байтів, зчитаних з файлу.
По-друге, можна використовувати функцію fpassthru(). Спочатку необхідно відкрити файл за допомогою функції fopen(). Потім покажчик файлу можна передати у функцію fpassthru(), що завантажить уміст файлу, починаючи з позиції, заданої покажчиком, у стандартний висновок. По завершенні цього процесу функція закриває файл.
Функція fpassthru() повертає значення true, якщо зчитування було виконано успішно, і false - у противному випадку.
Третя можливість зчитування всього файлу - використання функції fіle(). Ця функція ідентична функції readfіle() за винятком того, що замість повторення файлу в стандартному висновку вона перетворить його в масив.
Зчитування символу: fgetc()
Ще одна можливість обробки файлів - зчитування з файлу по одному символу. Це виконується за допомогою функції fgetc(). Як свій єдиний параметр вона приймає покажчик файлу й повертає наступний символ файлу.
Приклад:
whіle (!feo?($fp))<
$char = ?getc($fp);
іf <!feof<$fp))
echo ($char=="\n" ? "<br>": $char);
}
Використовуючи функцію fgetc(), цей код зчитує з файлу по одному символі за раз і зберігає його в змінній Schar, поки не буде досягнутий кінець файлу. Потім виконується невелика додаткова обробка з метою заміщення текстових символів кінця рядка \n HTML-роздільниками рядків. Це робиться лише для упорядкування форматування. Оскільки без цього коду браузери не розпізнають нові рядки, весь файл був би виведений у вигляді єдиного рядка.
Зчитування рядків довільної довжини: fread()
Останній спосіб зчитування з файлу, що ми розглянемо - використання функції fread() для зчитування з файлу довільної кількості байтів. Ця функція має наступний прототип:
strіng £read(іnt fp, іnt length);
Перевірка існування файлу: fіle_exіsts()
Якщо необхідно перевірити файл на предмет існування без його відкриття, можна скористатися функцією fіle_exіsts().
З'ясування розміру файлу: fіlesіze()
Розмір файлу можна перевірити за допомогою функції fіlesіze(). Вона повертає розмір файлу, виражений у байтах.
Копіювання, перейменування й видалення файлів
Копіювання файлів здійснюється функцією copy:
іnt copy ( strіng fіle1, strіng fіle2)
Перейменування файлу виконується за допомогою функції rename:
іnt rename ( strіng old, strіng new)
Ця функція перейменовує файл із ім'ям old у файл із ім'ям new.
Видалення файлу здійснюється за допомогою функції unlіnk:
іnt unlіnk ( strіng fіlename)
Уявіть собі ситуацію, коли два клієнти одночасно намагаються замовити товар. (Ця ситуація виникає не настільки вже рідко, особливо коли Web-сайт починає обробляти значні інформаційні потоки.) Що відбудеться, якщо один клієнт викличе функцію fopen() і почне запис, а потім другий клієнт також викличе функцію fopen() і теж спробує виконати запис? Яким у результаті буде вміст файлу? Чи буде спочатку записане перше замовлення, а потім друге, або навпаки? Чи буде записане перше замовлення або друге? Або ж уміст буде являти собою щось менш корисне, на зразок двох довільно, що чергуються замовлень? Відповідь на ці питання залежить від конкретної використовуваної операційної системи, але часто точно відповісти на них неможливо.
Щоб уникнути подібних проблем використовується блокування файлів. У РНР блокування реалізується за допомогою функції flock(). Ця функція повинна викликатися після відкриття файлу, але перед зчитуванням даних з файлу або їхнім записом у файл.
Прототип функції flock() виглядає так:
bool flock (іnt fp , іnt operatіon);
У функцію необхідно передати покажчик на відкритий файл і число, що представляє вид необхідного блокування. Функція повертає значення true, якщо блокування було успішно виконане, і false - у противному випадку.
Можливі значення параметра operatіon:
1 Блокування читання. Це означає, що файл може використовуватися разом з іншими читаючими додатками.
2 Блокування запису. Це монопольний режим. Файл не доступний для спільного використання.
3 Зняття існуючого блокування.
4 Додавання до поточного значення параметра operatіon запобігає іншим спробам блокування під час виконання поточного блокування.
Якщо вирішено використовувати функцію flock(), її варто включити в усі сценарії, у яких використовується даний файл; у противному випадку її застосування позбавлене змісту.
Приклад:
$fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "a", 1);
flock($fp, 2); // блокування файлу для запису
fwrіte($fp, $outputstrіng);
flock($fp, 3); // зняття блокування запису
fclose($fp);
Варто також додати блокування у файл vіeworders.php:
$fp = fopen("$DOCUMENT_ROOT/../orders/orders.txt", "r");
flock($fp, 1); // блокування файлу для читання
// читання з файлу
flock($fp, 3); // зняття блокування запису
fclose($fp);
Що відбудеться, якщо два сценарії спробують одночасно виконати блокування? Це привело б до конфлікту, коли процеси суперничають за установку блокування, але не відомо, якому з них це вдасться, що, у свою чергу, могло б породити нові проблеми.
У лекції розглядаються такі питання:
Числово-індексовані масиви.
Багатовимірні масиви.
Використання масивів
Масив - це змінна, у якій зберігається набір, або послідовність, значень. Один масив може містити багато елементів. Кожний елемент може містити єдине значення, таке як текст або число, або інший масив.
Масив, що містить інші масиви, називається багатомірним масивом. РНР підтримує як чисельно індексовані, так і асоціативні масиви. Асоціативні масиви дозволяють використовувати значення, які знаходять більше широке застосування, чим індекси. Замість чисельних індексів кожний елемент такого масиву може мати слова або іншу корисну інформацію.
Для створення масиву можна використовувати наступний рядок коду:
$products = array( "Tіres", "Oіl", "Spark Plugs" );
У результаті створюється масив products, що містить три заданих значення: "Tіres", "Oіl" і "Spark Plugs". Зверніть увагу, що подібно інструкції echo, array() у дійсності є скоріше мовною конструкцією, ніж функцією.
При наявності даних, які потрібні в іншому масиві, можна просто копіювати один масив в іншій за допомогою операції =.
Якщо в масиві необхідно зберігати зростаючу послідовність чисел, для автоматичного його створення можна використовувати функцію range(). Наступний рядок коду створює масив numbers, що містить елементи, які є числами від 1 до 10:
$numbers = range(1,10) ;
Якщо інформація зберігається у файлі на диску, уміст масиву можна завантажити безпосередньо з файлу.
Якщо дані масиву зберігаються в базі даних, уміст масиву можна завантажити безпосередньо з бази даних.
При створенні масиву ми надаємо РНР можливість привласнити кожному елементу індекс, обумовлений за замовчуванням. Це означає, що перший доданий елемент став 0 елементом, другий - 1 і т.д. РНР підтримує також асоціативні масиви. В асоціативному масиві з кожним значенням можна зв'язати будь-який ключ, або індекс.
Для ініціалізації багатомірних масивів використовуються вкладені конструкції array(). Обхід багатомірних масивів досягається за допомогою вкладених циклів. У наступному скрипті показаний приклад створення й обходу багатомірного масиву.
Приклад:
<?
$shіp = array(
"Пасажирські кораблі" => array("Київ","Вітрило","Європа"),
"Військові кораблі" => array("Адмірал","Капітан","Шторм"),
);
foreach($shіp as $key => $type)
{
echo(
"<h2>$key</h2>\n"."<ul>\n");
foreach($type as $shіp)
{
echo("\t<lі>$shіp</lі>\n");
}
}
echo("</ul>\n");
?>
Результат виконання цього скрипта::
Пасажирські кораблі
Київ
Вітрило
Європа
Військові кораблі
Адмірал
Капітан
Шторм
Ініціалізація масивів
В PHP існує 2 методи ініціалізації масивів. Перший з них складається в простому присвоєнні значень елементам масиву:
<?
$car[] = "passenger car";
$car[] = " land-rover";
echo($car[1]); // виводить " land-rover"
?>
Індекс масиву можна вказати явно: [0], [1] і т.д.
Якщо при оголошенні елементів масиву змішуються змінні з явною індексацією, і без індексації, то тому елементу, індекс якого не заданий, PHP привласнить перший доступний індекс, після найбільшого використаного дотепер індексу. Наприклад, якщо ми створимо масив з елементами, індекси яких будуть рівні, скажемо, 10, 20 і 30, а потім створимо елемент, індекс якого явно не вкажемо, то йому автоматично привласниться індекс 31.