А это клавиатура, с помощью которой я творю...
http://kurepin.ru/php/files/
Rambler's Top100
Пишем на PHP: Работа с файлами (чтение-запись)

Я понимаю ваше нетерпение. Мы все что-то пишем-пишем, а пока еще никакой визуализации.

Если вы — начинающий программист, то наверняка привыкли работать так: строчку добавил — проверил выполнение, еще строчку добавил — опять проверил, как программа работает.

А мы тут пишем, но не проверяем. Все верно, не проверяем. Более того, я вам обещаю, что в тех листингах, что мы уже написали, достаточно много ошибок. В основном, конечно, синтаксических. Где-то забыли точку с запятой поставить, где-то $this-> к переменной забыли приписать. Да мало ли что еще...

Но это так и надо. Я не кривлю душой, я действительно все пишу прямо в текстах курса, без какой-либо проверки их в работе.

Так вот, друзья мои. Привыкайте писать именно так! Рождайте в голове задумки и выкладывайте их в виде программного кода. Проверить и отладить вы их всегда успеете. А как показывает практика, в процессе написания нового модуля очень даже часто возникает "задним числом" какая-то новая идея, заставляющая нас возвращаться назад и что-то переделывать. И что, снова тестировать и выискивать глюки? Да ничего подобного — так можно всю жизнь писать один проект.

Но я вам обещаю. Еще несколько занятий, и мы перейдем к классу class_out, перейдем к визуализации данных и добавления их через web-форму, с использованием написанных функций. Готовьте дизайн для вашего нового сайта!

А сегодня мы займемся файловыми процедурами. Нам же надо уметь сохранять тексты и другие файлы. Вот и поучимся.

В PHP существует достаточно много разных механизмов для работы с файлами различных типов. Мы разделим все файлы на два основных типа: текстовые файлы и файлы данных (картинки, музыка, исполняемый код и все остальные типы файлов).

Отличие между текстовыми файлами и остальными состоит в том, что текстовые файлы можно разделить на строки (окончанием строки служит символ EOL — "\n" — Enter). И по этим строкам файл можно читать, писать и все остальное.

Для начала вспомним, что во всех системах файл необходимо открыть, прежде чем что-то с ним сделать.

Открыть файл нам поможет функция PHP fopen().

Оформляется открытие файла так:

$r=fopen('path_to_file','mode');

где:
$r — указатель на открытый файл. Он нам нужен, чтобы обращаться к нужному файлу, когда их открыто более одного.
path_to_file — абсолютный путь к файлу на диске сервера.
mode — режим, в котором открывается файл.

В PHP можно открыть файл в следующих режимах:

'r' — только для чтения.

'r+' — для чтения и записи

'w' — только для записи

'a-' — только для записи. То есть файл открывается для записи, но при этом курсор устанавливается в конец файла. Можно сказать, что это открытие файла для дозаписи.

'a+' — тоже, что и a-, но еще доступно и чтение.

В каждом режиме, где присутствует возможность записи, PHP создаст вам новый файл, если такового не существует в момент открытия. При условии, конечно, что у вас есть на это права в системе.

На самом деле, я не рекомендую вам забивать себе голову всеми этими режимами. Достаточно запомнить два:

'r' — читать (read)

'w' — писать (write)

А к остальным режим нужно обращаться только в том случае, когда не получается реализовать задачу этими двумя, которых почти всегда достаточно.

После того, как файл был открыт, с ним можно проводить операции по записи и чтению данных.

Помните, я как-то писал, что все структуры, имеющие открывающие и закрывающие формы, надо сразу закрывать, как только их открыли, а уж потом писать тело структуры? Вот к файлам это так же относится.

Прежде чем перейти к чтению и записи содержимого файла, давайте его закроем:

fclose($r);

Не сложно. $r — это указатель на открытый файл (вспомните функцию открытия файла).

    После выполнения скрипта PHP сам закроет все файлы, которые вы забыли закрыть. Но если вам важно сохранить в файлах именно то, что надо — сделайте это сами.


Теперь приступим к тирании содержимого файла.

Для начала, я хочу вам показать, как читается и записывается обычный файл с данными (я пронумерую строки для простоты комментирования).

$file_name='/home/roma/address.txt'; // 1

$r=fopen($filename,'r'); // 2

$text=fread($r,filesize($file_name)); // 3

fclose($r);  // 4

$text=ereg_replace('213-','670-',$text); // 5

$w=fopen($file_name,'w'); // 6

fwrite($w,$text);  // 7

fclose($w);  // 8

По строчкам:

1. Определили в переменную путь к файлу. Представим, что в этом файле содержится копия вашей записной книжки.

2. Открываем этот файл для чтения.

3. Читаем в переменную $text содержимое всего файла. Функция filesize(), как раз, сообщает нам размер файла, который мы собрались читать. Зная, что файл не очень большой, мы решаем прочесть в переменную все его содержимое разом.

4. Закрываем файл.

5. А почему мы все это делаем? А потому, что у массы наших друзей сменились первые три цифры телефона: наконец сменили старую АТС на новую цифровую. Функция PHP preg_replace поможет нам заменить все 213- на 670- по всему содержимому переменной $text. А измененный вариант мы записываем обратно в $text.

6. Открываем все тот же файл, но теперь для записи.

7. Записываем в файл содержимое переменной $text.

8. Закрываем файл.

Вот так. Тоже все не сложно.

    Только я прошу не забывать, что работа с файлами чревата множеством самых разных ошибок. Поэтому, как минимум, все открытия файлов должны обязательно сопровождаться проверкой на результат попытки открытия или создания файла. На его существование, если вы его собрались читать и так далее. Я сегодня не стану останавливаться на ошибках — будем рассматривать идеальный безошибочный вариант, но в дальнейшем (в нашей программе) вы обязательно увидите все необходимые проверки.

А теперь напишем ту же самую процедуру, но будем работать с файлом, зная, что это текстовый файл, разбитый на строки. При этом, необходимо предположить, что длина одной строки не более nnn символов (байт). Я думаю, что у нас не более 1024 символов в одной текстовой строке(1K).

$file_name='/home/roma/address.txt'; // 1

$file_new_name='/home/roma/address_new.txt'; // 2

$r=fopen($filename,'r'); // 3

$w=fopen($file_new_name,'w'); // 4

while($str=fgets($r,1024)) // 5
{
  $str=ereg_replace('213-','670-',$str); // 6

  fputs($w,$str); // 7
}

fclose($r);  // 8

fclose($w);  // 9

1. Определяем путь к файлу для чтения

2. Определяем путь к файлу для записи

3. Открываем файл для чтения

4. Открываем другой файл для записи

5. Начинам читать по одной строке в переменную $str из файла $r до тех пор, пока не достигнем конца файла (EOF — End Of File). Причем, строка читается либо до знака конца строки (EOL — End Of Line), либо до 1024-го символа. Это свойство функции чтения строки fgets().

6. Проводим замену 213 на 670.

7. Записываем строку $str в файл $w.

8, 9. После окончания цикла закрываем оба файла.

Немного длиннее получилось, но насколько правильнее!

Есть разные причины, по которым этот метод можно считать более правильным, чем предыдущий, но я сообщу вам самые веские.

Представьте, что у вас случайно файл оказался размером во много мегабайт: скрипт попросту не выполнится, так как для каждого скрипта отводится ограниченное пространство в оперативной памяти (по умолчанию это 5Mb, если не ошибаюсь).

Или подобную функцию вызвали сразу сто посетителей страницы (например, у вас сто модемных пользователей не спеша тянут с сайта mp3-музыку): у вас просто случится переполнение оперативной памяти сервера, и вы получите по мозгам от вашего администратора.

А еще мы во втором примере прочитали один файл, а записали результат обработки в другой: может случиться так, что произойдет ошибка во время записи данных в файл. В этом случае у нас останется исходная копия данных и нам не придется рвать на голове волосы, разыскивая данные на кассетах с бэкапом.

И это все касается не только обработки текстовых файлов, но файлов данных. Особенно — файлов данных, так как текстовые файлы обычно имеют не такой уж большой размер, как картинки или те же mp3-файлы.

Кстати, в PHP есть замечательная функция readfile(), которая просто читает файл и отдает его в стандартный output (в нашем случае это может быть посетитель сайта) небольшими порциями, не перегружая оперативную память, с требуемой скоростью. Мы ей тоже воспользуемся где-нибудь, я надеюсь.

Завтра напишем функцию добавление новой работы в папку нашего веб-обзорщика.

До завтра!

[шаг назад] [печатать] [в начало сайта]



copyright ©2000-2017 Ruslan Kurepin