Материал: 09

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

9. Лекція:

Тема:Робота з файловою системою

Мета: В лекції обговорюються питання, пов'язані із створенням файлів, читанням даних з файлу, видалення файлу, а також перевірка наявності файлу на сервері. (Функції fopen, fwrite, fclose, file, fget, unlink, file_exists.) Приклад - завантаження файлу на сервер за допомогою web-інтерфейсу.

ПЛАН

1 Створення файлу

2 Запис даних у файл

3 Читання даних з файлу

4 Перевірка існування файлу

5 Видалення файлу

6 Завантаження файлу на сервер

1 Створення файлу

Функція fopen

Взагалі кажучи, в PHP не існує функції, призначеної саме для створення файлів. Більшість функцій працює з вже існуючими файлами у файловій системі серверу. Є декілька функцій, які дозволяють створювати тимчасові файли, або, файли з унікальним для поточної директорії ім'ям. А ось для того, щоб створити найзвичайніший файл, потрібно скористатися функцією, яка відкриває локальний або віддалений файл. Називається ця функція fopen(). Що значить "відкриває файл"? Це значить, що fopen пов'язує даний файл з потоком управління програми. Причому скріплення буває різним залежно від того, що ми хочемо робити з цим файлом: читати його, записувати в нього дані або робити і те і інше. Синтаксис цієї функції такий:

resource fopen ( ім’я_файлу, тип_доступу [, use_include_path])

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

Параметр ім’я_файлу повинен бути рядком, що містить правильне локальне ім'я файлу або URL-адресу файлу в мережі. Якщо ім'я файлу починається з вказівки протоколу доступу (наприклад, http://... або ftp://...), то інтерпретатор вважає це ім'я адресою URL і шукає обробник вказаного в URL протоколу. Якщо обробник знайдений, то PHP перевіряє, чи дозволено працювати з об'єктами URL як із звичайними файлами (директива allow_url_fopen ). Якщо allow_url_fopen=off, то функція fopen викликає помилку і генерується попередження. Якщо ім'я файлу не починається з протоколу, то вважається, що вказано ім'я локального файлу. Щоб відкрити локальний файл, потрібно, щоб PHP мав відповідні права доступу до цього файлу.

Параметр use_include_path, встановлений в значення 1 або TRUE, примушує інтерпретатор шукати вказаний в fopen() файл в include_path. Нагадаємо, що include_path - це директива з файлу настройок PHP, задаюча список директорій, в яких можуть знаходитися файли для включення. Окрім функції fopen() вона використовується функціями include() і require().

Параметр тип_доступу може приймати одне з наступних значень (див. таб. 9.1).

Таблиця 9.1. Значення приймаються параметром тип доступу

r

Відкриває файл тільки для читання; встановлює вказівник позиції у файлі на початок файлу.

r+

Відкриває файл для читання і запису; встановлює вказівник файлу на його початок.

w

Відкриває файл тільки для запису; встановлює вказівник файлу на його початок і усікає файл до нульової довжини. Якщо файл не існує, то намагається створити його.

w+

Відкриває файл для читання і запису; встановлює вказівник файлу на його початок і усікає файл до нульової довжини. Якщо файл не існує, то намагається створити його.

а

Відкриває файл тільки для запису; встановлює вказівник файлу в його кінець. Якщо файл не існує, то намагається створити його.

a+

Відкриває файл для читання і запису; встановлює вказівник файлу в його кінець. Якщо файл не існує, то намагається створити його.

x

Створює і відкриває файл тільки для запису; поміщає вказівник файлу на його початок. Якщо файл вже існує, то fopen() повертає false і генерується попередження. Якщо файл не існує, то робиться спроба створити його. Цей тип доступу підтримується починаючи з версією PHP 4.3.2 і працює тільки з локальними файлами.

x+

Створює і відкриває файл для читання і запису; поміщає вказівник файлу на його початок. Якщо файл вже існує, то fopen() повертає false і генерується попередження. Якщо файл не існує, то робиться спроба створити його. Цей тип доступу підтримується, починаючи з версією PHP 4.3.2, і працює тільки з локальними файлами.

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

<?php

$h = fopen("my_file.html","w");

/* відкриває на запис файл my_file.html якщо він існує, або створює порожній

файл з таким ім'ям, якщо його ще нема */

$h = fopen("dir/another_file.txt","w+");

/* відкриває на запис і читання або створює файл another_file.txt в директорії dir */

$h = fopen(

"http://www.server.ru/dir/file.php","r");

/* відкриває на читання файл, що знаходиться по вказаному адресу*/

?>

Приклад 9.1. Використовування функції fopen()

Створюючи файл, потрібно враховувати, під якою операційною системою ви працюєте, і під якою ОС імовірно цей файл читатиметься. Річ у тому, що різні операційні системи по-різному відзначають кінець рядка. В Unix-подібних ОС кінець рядка позначається \n, в системах типа Windows - \r\n. Windows пропонує спеціальний прапор t для перекладу символів кінця рядка систем типа Unix в свої символи кінця рядка. В протилежність цьому існує прапор b, що використовується частіше за все для бінарних файлів, завдяки якому такої трансляції не відбувається. Використовувати ці прапори можна, просто дописавши їх після останнього символу вибраного типу доступу до файлу. Наприклад, відкриваючи файл на читання, замість r слід використовувати rt, щоб перекодувати всі символи кінця рядка в \r\n. Якщо не використовувати прапор b при відкритті бінарних файлів, то можуть з'являтися помилки, пов'язані із зміною вмісту файлу. З міркувань переносимості програми на різні платформи рекомендується завжди використовувати прапор b при відкритті файлів за допомогою fopen().

Що відбувається, якщо відкрити або створити файл за допомогою fopen не вдається? В цьому випадку PHP генерує попередження, а функція fopen повертає як результат своєї роботи значення false. Такого роду попередження можна "подавити" (заборонити) за допомогою символу @.

Наприклад, така команда не виведе попередження, навіть якщо відкрити файл не вдалося:

$h = @fopen("dir/another_file.txt","w+");

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

Перш ніж відповісти на ці питання, розглянемо, як закрити встановлене за допомогою fopen() з'єднання.

Закриття з'єднання з файлом

Після виконання необхідних дій з файлом, будь то читання або запис даних або що-небудь інше, з'єднання, встановлене з цим файлом функцією fopen(), потрібно закрити. Для цього використовують функцію fclose(). Синтаксис у неї наступний:

fclose (вказівник на файл)

Ця функція повертає TRUE, якщо з'єднання успішно закрито, і FALSE – в протилежному випадку. Параметр цієї функції повинен указувати на файл, успішно відкритий, наприклад, за допомогою функції fopen().

<?php

$h = fopen("my_file.html","w");

fclose($h);

?>

Приклад 9.2. Використовування функції fclose()

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

2 Запис даних у файл

Функція fwrite

Для того, щоб записати дані у файл, доступ до якого відкритий функцією fopen(), можна використовувати функцію fwrite(). Синтаксис у неї наступний:

int fwrite ( вказівник на файл, рядок [, довжина])

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

В результаті своєї роботи функція fwrite() повертає число записаних байтів або false, у разі помилки.

Приклад 9.3. Хай в нашій робочій директорії немає файлу my_file.html. Створимо його і запишемо в нього рядок тексту:

<?php

$h = fopen("my_file.html","w");

$text = "цей текст запишемо у файл.";

if (fwrite($h,$text))

echo "Запис пройшов успішно";

else

echo "Відбулася помилка при записі даних";

fclose($h);

?>

Приклад 9.3. Використовування функції fwrite()

В результаті роботи цього скрипта в браузері ми побачимо повідомлення про те, що запис пройшов успішно, а у файлі my_file.html з'явиться рядок "Цей текст запишемо у файл.". Якби цей файл існував до того, як ми виконали цей скрипт, всі дані, що знаходяться в ньому, були б видалені.

Якщо ж ми напишемо такий скрипт:

<?php

$h = fopen("my_file.html","a");

$add_text = "додамо текст у файл.";

if(fwrite($h,$add_text,7))

echo "Додавання тексту пройшло успішно<br>";

else echo "Відбулася помилка при додаванні даних<br>";

fclose($h);

?>

то до рядка, вже існуючого у файлі my_file.html, додасться ще сім символів з рядка, що міститься в змінній $add_text, тобто слово "Додамо"

Функція fwrite() має псевдонім fputs(), що використовується таким же чином, що і сама функція.

Далі ми розглянемо, які методи читання даних з файлу пропонує мова PHP.

3 Читання даних з файлу

Якщо ми хочемо прочитати дані з існуючого файлу, однієї функції fopen(), як і у випадку із записом даних, недостатньо. Вона лише повертає вказівник на відкритий файл, але не прочитує жодного рядка з цього файлу. Тому для того, щоб прочитати дані з файлу, потрібно скористатися однією із спеціальних функцій: file, readfile, file_get_contents, fread, fgets і т.п.

Функція fread

Ця функція здійснює читання даних з файлу. Її можна використовувати і для читання даних з бінарних файлів, не боючись їх пошкодження. Синтаксис fread() такий:

string fread (вказівник на файл, довжина)

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

В результаті роботи функція fread() повертає рядок зі зчитаною з файлу інформацією.

Як ви помітили, в цій функції параметр довжина - обов'язковий. Отже, якщо ми хочемо зчитувати весь файл в рядок, потрібно знати його довжину. PHP може самостійно обчислити довжину вказаного файлу. Для цього потрібно скористатися функцією filesize(ім'я файлу). У разі помилки ця функція поверне false. На жаль, її можна використовувати тільки для отримання розміру локальних файлів.

Приклад 9.4. Прочитаємо вміст файлу my_file.html

<?php

$h = fopen("my_file.html","r+");

// відкриваємо файл на запис і читання

$content = fread($h, filesize("my_file.html"));

// прочитуємо вміст файлу в рядок

fclose($h); // закриваємо з'єднання з файлом

echo $content;

// виводимо вміст файлу на екран браузера

?>

Приклад 9.4. Використовування функції fread()

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

Функція filesize() кешує результати своєї роботи. Якщо змінити вміст файлу my_file.html і знову запустити приведений вище скрипт, то результат його роботи не зміниться. Більш того, якщо запустити скрипт, що прочитує дані з цього файлу за допомогою іншої функції (наприклад, fgets ), то результат може виявитися таким, неначебто файл не змінився. Щоб цього уникнути, потрібно очистити статичний кеш, додавши в код програми команду clearstatcache() ;

Функція fgets

За допомогою функції fgets() можна зчитувати з файлу рядок тексту. Синтаксис цієї функції практично такий же, як і у fread(), за винятком того, що довжину прочитуваного рядка указувати необов'язково:

string fgets ( вказівник на файл [ довжина])

В результаті роботи функція fgets() повертає рядок завдовжки ( довжина-1 ) байт з файлу, на який указує вказівник на файл. Читання закінчується, якщо прочитано ( довжина-1 ) символів або зустрівся символ перенесення рядка або кінець файлу. Нагадаємо, що в PHP один символ - це один байт. Якщо довжина прочитуваного рядка не вказана (дана можливість з'явилася починаючи з PHP 4.2.0), то прочитується 1 Кбайт (1024 байт) тексту або, що те ж саме, 1024 символи. Починаючи з версією PHP 4.3, якщо параметр довжина не заданий, прочитується рядок цілком. У разі помилки функція fgets() повертає false. Для версій PHP починаючи з 4.3 ця функція безпечна для двійкових файлів.

<?php

$h = fopen("my_file.html","r+");

$content = fgets($h,2);

// зчитує перший символ з першого рядка файлу my_file.html

fclose($h);

echo $content;

?>

Приклад 9.5. Використовування функції fgets()

Обидві функції, fread() і fgets(), припиняють прочитування даних з файлу, якщо зустрічають кінець файлу. В PHP є спеціальна функція, перевіряюча, чи досяг вказівник позиції файлу до кінця файлу. Це булева функція feof(), як параметр якій передається вказівник на з'єднання з файлом.

Наприклад, от так можна зччитати всі рядки файлу my_file.html:

<?php

$h = fopen("my_file.html","r");

while (!feof ($h)) {

$content = fgets($h);

echo $content,"<br>";

}

fclose($h);

?>

Функція fgetss

Існує різновид функції fgets() - функція fgetss(). Вона теж дозволяє прочитувати рядок з вказаного файлу, але при цьому видаляє з нього все html-теги, що зустрілися, за виключенням деяких. Синтаксис fgetss() такий:

string fgetss(вказвник на файл, довжина [, допустимі теги])

Зверніть увагу, що тут аргумент довжина обов'язковий.

Приклад 9.6. Хай у нас є файл my_file.html наступного змісту:

<h1>Без праці не виймеш і рибку із ставка.</h1>

<b>Тихше їдеш - далі будешь</b> У семи няньок<i> дитя без ока</i>.

Виведемо на екран всі рядки файлу my_file.html, видаливши з них все теги, окрім <b> і <i>:

<?php

$h = fopen("my_file.html","r");

while (!feof ($h)) {

$content = fgetss($h,1024,'<b><i>');

echo $content,"<br>";

}

fclose($h);

?>

Приклад 9.6. Використовування функції fgetss()

В результаті роботи цього скрипта одержимо:

Без праці не виймеш і рибку із ставка. Тихше їдеш – далі будеш У семи няньок дитя без ока.

Функція fgetc

Природно, якщо можна прочитувати інформацію з файлу порядково, то можна прочитувати її і посимвольно. Для цього призначена функція fgetc(). Легко здогадатися, що синтаксис у неї наступний:

string fgetc ( вказівник на файл )

Ця функція повертає символ з файлу, на який посилається вказівник на файл, і значення, обчислюване як FALSE, якщо зустрівся кінець рядка.

От так, наприклад, можна зчитати файл по одному символу:

<?php

$h = fopen("my_file.html","r");

while (!feof ($h)) {

$content = fgetc($h);

echo $content,"<br>";

}

fclose($h);

?>

Насправді для того, щоб прочитати вміст файлу, відкривати з'єднання з ним за допомогою функції fopen() зовсім не обов'язково. В PHP є функції, які дозволяють робити це, використовуючи лише ім'я файлу. Це функції readfile( ), file( ) і file_get_contents( ). Розглянемо кожну з них докладніше.

Функція readfile

Синтаксис:

int readfile ( ім’я_файлу [, use_include_path])

Функція readfile() прочитує файл, ім'я якого передано їй як параметр ім’я_файлу, і виводить його вміст на екран. Якщо додатковий аргумент use_include_path має значення TRUE, то пошук файлу із заданим ім'ям проводиться і по директоріях, що входять в include_path.

В програму ця функція повертає число зчитаних байтів (символів) файлу, а у разі помилки - FALSE. Повідомлення про помилку в цій функції можна подавити оператором @.

Приклад 9.7. Наступний скрипт виведе на екран вміст файлу my_file1.html і розмір цього файлу, якщо він існує. Інакше виведеться наше повідомлення про помилку - рядок "Error in readfile".

<?php

$n = @readfile ("my_file1.html");

/* виводить на екран вміст файлу і записує його розмір в змінну $n */

if (!$n) echo "Error in readfile";

/* якщо функція readfile() виконалася з помилкою, то $n=false і виводимо повідомлення про помилку */

else echo $n;

// якщо помилки не було, то виводимо кількість зчитаних символів

?>

Приклад 9.7. Використовування функції readfile()

За допомогою функції readfile() можна читати вміст віддалених файлів, указуючи їх URL-адресу як ім'я файлу, якщо ця опція не відключена в настройках серверу.

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

Функція file

Функція file() призначена для прочитування інформації з файлу в змінну типу масив. Синтаксис у неї такий же, як і у функції readfile(), за винятком того, що в результаті роботи вона повертає масив:

array file ( string $filename [, int $flags = 0 [, resource $context ]] )

Що за масив повертає ця функція? Кожний елемент даного масиву є рядком у файлі, інформацію з якого ми прочитуємо (його ім'я задано аргументом ім’я_файлу ). Символ нового рядка теж включається в кожний з елементів масиву. У разі помилки функція file(), як і всі вже розглянуті, повертає false. Додатковий аргумент use_include_path знову ж таки визначає, шукати чи ні даний файл в директоріях include_path. Відкривати віддалені файли за допомогою цієї функції теж можна, якщо не заборонено сервером.

Наприклад, у нас є файл my_file.html наступного змісту:

<h1>Без праці не виймеш і рибку із ставка.</h1>

<b>Тише їдеш - далі будешь</b>