PHP: чтение PHP-файла. Работа с файлами в PHP: чтение, запись и рекомендации. Как правильно читать файлы с помощью PHP Php данные из файла

string fgets (resource handle [, int length])

Возвращает строку размером в length - 1 байт, прочитанную из дескриптора файла, на который указывает параметр handle . Чтение заканчивается, когда количество прочитанных байтов достигает length - 1, по достижении конца строки (который включается в возвращаемое значение) или по достижении конца файла (что бы ни встретилось первым). Если длина не указана, по умолчанию ее значение равно 1 килобайту или 1024 байтам.

В случае возникновения ошибки функция возвращает FALSE .

Наиболее распространенные ошибки:

Программисты, привыкшие к семантике "C" функции fgets() , должны принимать во внимание разницу в том, каким образом возвращается признак достижения конца файла (EOF).

Указатель на файл должен быть корректным и указывать на файл, успешно открытый функциями fopen() или fsockopen() .

Ниже приведен простой пример:


Пример 1. Построчное чтение файла

$handle = fopen ("/tmp/inputfile.txt" , "r" );
while (! feof ($handle )) {
$buffer = fgets ($handle , 4096 );
echo $buffer ;
}
fclose ($handle );
?>

Замечание: Параметр length стал необязательным, начиная с PHP версии 4.2.0. Если этот параметр опущен, длина строки принимается за 1024. С версии PHP 4.3, отсутствие параметра length будет приводить к чтению потока до конца строки. Если длина большинства строк в файле превышает 8 килобайт, наиболее эффективным решением в отношении ресурсов, используемых скриптом, будет указание максимальной длины строки.

Замечание: Данная функция может корректно обрабатывать двоичные данные, начиная с версии PHP 4.3. Более ранние версии не обладали этой функциональностью.

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

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

А мы тут пишем, но не проверяем. Все верно, не проверяем. Более того, я вам обещаю, что в тех листингах, что мы уже написали, достаточно много ошибок. В основном, конечно, синтаксических. Где-то забыли точку с запятой поставить, где-то $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 создаст вам новый файл, если такового не существует в момент открытия. При условии, конечно, что у вас есть на это права в системе.

"w " — писать (w rite)

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

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

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

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

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 (в нашем случае это может быть посетитель сайта) небольшими порциями, не перегружая оперативную память, с требуемой скоростью. Мы ей тоже воспользуемся где-нибудь, я надеюсь.

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

Под работой с файлами в PHP подразумевается чтение из файла и запись в файл различной информации. Совершенно очевидно, что работать с файлами приходится много, поэтому любой PHP-программист обязан уметь считывать из файла и записывать в файл .

Последовательность работы с файлами в PHP такая:

  1. Открыть файл.
  2. Выполнить необходимые действия.
  3. Закрыть файл.

Как видите, последовательность работы с файлами напоминает работу с файлами через обычный проводник. Только здесь вся работа выполняется автоматически самим PHP-скриптом .

Начнём с первого пункта - открытие файла. Файл открывается с помощью функции fopen() . Первый параметр - это путь к файлу, а второй параметр - модификатор . Давайте сразу разберём возможные модификаторы:

  1. a - открывает файл только для записи, причём указатель помещается в конец файла.
  2. a+ a , но также файл открывается ещё и для чтения.
  3. r - открывает файл только для чтения, а указатель устанавливается в начало файла.
  4. r+ - то же самое, что и модификатор r , но также файл открывается ещё и для записи.
  5. w - открывает файл только для записи, указатель устанавливает в начало файла и стирает всё содержимое файла.
  6. w+ - то же самое, что и модификатор w , только файл открывается также и для чтения.

Также различают два режима работы с файлами: бинарный (обозначается b ) и текстовый (обозначается t ). Если Вы работаете с обычным текстовым файлом, то выбирайте текстовый режим, а если, например, с изображением, то бинарный.

Это все основные модификаторы, которых Вам вполне хватит. Теперь давайте узнаем, как закрыть файл. Закрывается файл с помощью функции fclose() .

Теперь перейдём к чтению файла с помощью функции fread() . И давайте, наконец-то, приведу пример:

$contents = "";
while (!feof($handle))
$contents .= fread($handle, 4096);
fclose($handle);
?>

В данном примере мы сначала открываем файл для чтения в текстовом режиме (модификатор rt ). Функция fopen() возвращает так называемый дескриптор , с помощью которого можно общаться с файлом, и записываем его в переменную handle . Затем мы в цикле while() до тех пор, пока не достигнут конец файл, считываем содержимое каждый раз по 4096 символов, которые записываем в переменную contents . После завершения процесса считывания - закрываем файл, вновь с помощью дескриптора файла.

Теперь перейдём к записи с помощью функции fwrite() :

$handle = fopen("files/a.txt", "at");
$string = "This is text";
fwrite($handle, $string);
fclose($handle);
?>

После запуска этого скрипта, в файле a.txt добавится строка "This is text ".

Особо внимательные читатели обратили внимание на указатели, о которых я писал чуть выше. Указатель - это текущая позиция воображаемого "курсора" в файле. Именно с него и начинается работа с файлом. Изменить положение указателя можно с помощью функции fseek() :

$handle = fopen("files/a.txt", "rt");
echo $contents."
";
fseek($handle, 0, SEEK_SET);
$contents = fread($handle, 3);
echo $contents."
";
?>

Таким образом, мы сначала считываем 3 символа (в результате, текущее положение указателя сдвигается на 3 позиции). Затем мы устанавливаем указатель на начало файла. И вновь считываем 3 символа. Как Вы и догадались, мы два раза считали одно и тоже. То есть первый раз 3 символа, потом вернулись назад, и вновь считали 3 символа. Также если у функции fseek() заменить SEEK_SET на SEEK_CUR , то тогда второй параметр будет не устанавливать позицию указателя, а сдвигать относительно текущего местоположения. Советую даже попрактиковаться с указателями, потому что для понимания это не так просто. Также рекомендую попытаться записать что-нибудь в файл при позиции указателя, например, в самом начале файла. И обязательно объясните полученный результат.

И, напоследок, хочется привести ещё пару функций, которые позволяют работать с файлами на самом простом уровне: file_put_contens() и file_get_contents() . Функция file_put_contents() записывает в файл, а функция file_get_contents() считывает содержимое из файла. Эти функции очень просты в применении, но возможностей там уже меньше (хотя, как правило, они и не нужны):

file_put_contents("files/a.txt", "This is text 2");
echo file_get_contents("files/a.txt");
?>

В данном скрипте мы сначала записали строку "This is text 2 " в файл, а потом считываем полученное содержимое и выводим его. Как видите, трудно придумать более простой способ чтения из файла и запись в файл .

Вот и все основные моменты работы с файлами в PHP .

PHP

file_exists("test.txt")//Существует ли файл? filesize("test.txt");//Узнаем размер файла //Возвращается временная метка: fileatime("test.txt");//Дата последнего обращения к файлу //date("d M Y", $atime); filemtime("test.txt");//Дата изменения файла //date("d M Y", $mtime); filectime("test.txt");//Дата создания файла(Windows) //date("d M Y", $ctime);

Файлы: режимы работы

PHP

resource fopen (string filename, string mode) // resource - возвращает указатель на файл в случае успешной работы, или FALSE в случае ошибки
Режим работы Описание
r открыть файл только для чтения;
r+ открыть файл для чтения и записи;
w открыть файл только для записи. Если он существует, то текущее содержимое файла уничтожается. Текущая позиция устанавливается в начало;
w+ открыть файл для чтения и для записи. Если он существует, то текущее содержимое файла уничтожается. Текущая позиция устанавливается в начало;
а открыть файл для записи. Текущая позиция устанавливается в конец файла;
а+ открыть файл для чтения и записи. Текущая позиция устанавливается в конец файла;
b обрабатывать бинарный файл. Этот флаг необходим при работе с бинарными файлами в ОС Windows.

Открытие и закрытие файлов в PHP

PHP

$fi = fopen("test.html", "w+") or die("Ошибка"); //Примеры $fi = fopen("http://www.you/test.html","r"); $fi = fopen("http://ftp.you/test.html", "r"); //Закрываем fclose($fi)

Чтение файлов в PHP

PHP

//Читаем файл fread(int fi, int length) $str = fread($fi, 5); // Читаем первые 5 символов echo $str; // так как курсор передвинулся $str = fread($fi, 12); // Читаем следующие 12 символов echo $str; fgets(int fi[, int length]) // Прочитать строку из файла fgetss(int fi, int length [, string allowable]) // Прочитать строку из файла и отбросить HTML-теги // string allowable - теги, которые необходимо оставить fgetc(int fi) //Считывает символ из файла

Изначально Запись будет происходить в начало файла, путем перезаписывания существующих данных, если они есть. Поэтому, если вам нужно записать что-то в конец файла, нужно установить соответствующий режим чтения , например, a+ .

Манипуляции с курсором в файлах PHP

PHP

int fseek(int fi, int offset [, int whence]) //Установка курсора // int fi - указатель на файл //offset - количество символов, на которые нужно передвинуться. //whence: //SEEK_SET - движение начинается с начала файла; //SEEK_CUR - движение идет от текущей позиции; //SEEK_END - движение идет от конца файла. fseek($fi, -10, SEEK_END); //Читаем последние 10 знаков $s = fread($fi, 10); $pos = ftell($fi); //Узнаем текущую позицию rewind($f)//сброс курсора bool feof($f) //конец файла

Прямая работа с файлами (данными) в PHP

PHP

array file(string filename) // Получаем содержимое файла в виде массива //Еще один вариант прямой работы с данными file_get_contents(string filename) //Чтение (получаем весь файл одной строкой) //Запись в файл (изначально перезаписывается) file_put_contents(string filename, mixed data[,int flag]); //FILE_APPEND // Запись в конец файла: file_put_contents("test.txt", "данные", FILE_APPEND); //Если записать массив, $array = array("I", "live"); file_put_contents("test.txt",$array); //то получим "Ilive"

Управление файлами в php

PHP

copy(string source, string destination); // Копирование файла rename(str oldname, str newname); // Переименование файла unlink(string filename); // Удаление файла

Загрузка файлов на сервер PHP

//Настрoйки PHP.ini file_uploads (on|off) // разрешаем.запрещаем загрузку файлов upload_tmp_dir // временная папка для загружаемых файлов. по умолчания временная папка upload_max_filesize (default = 2 Mb) // макс. размер загружаемого файла post_max_size // общий размер посылаемый формы (должен быть больше upload_max_filesize) //Простая загрузка

HTML

Работаем с файлами на сервере

PHP

//Принимаем данные $tmp = $_FILES["userfile"]["tmp_name"]; $name = $_FILES["userfile"]["name"]; //Перемещаем файл move_uploaded_file($tmp, name); move_uploaded_file($tmp, "upload/".name); // перенаправляем файл в папку upload // относительно текущего файла //Что в массиве $_FILES $_FILES["userfile"]["name"] // имя файла, например, test.html $_FILES["userfile"]["tmp_name"] // временное имя файла (путь) $_FILES["userfile"]["size"] // размер файла $_FILES["userfile"]["type"] // тип файла $_FILES["userfile"]["error"] // 0 - ошибок нет, число - есть

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

file_get_contents — Читает содержимое файла в строку

Описание

String file_get_contents (string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]])

Данная функция похожа на функцию file() с той только разницей, что file_get_contents() возвращает содержимое файла в строке, начиная с указанного смещения offset и до maxlen байт. В случае неудачи, file_get_contents() вернёт FALSE .

Использование функции file_get_contents() наиболее предпочтительно в случае необходимости получить содержимое файла целиком, поскольку для улучшения производительности функция использует технику отображения файла в память (memory mapping), если она поддерживается вашей операционной системой.

Замечание :

Если вы открываете URI содержащий спецсимволы, такие как пробел, вам нужно закодировать URI при помощи urlencode() .

Список параметров

Имя читаемого файла.

Use_include_path

Замечание :

Начиная с версии PHP 5 можно использовать константу FILE_USE_INCLUDE_PATH для поиска файла в include path .

context

Корректный ресурс контекста, созданный с помощью функции stream_context_create() . Если в использовании особого контекста нет необходимости, можно пропустить этот параметр передав в него значение NULL .

Смещение, с которого начнется чтение оригинального потока.

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

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

Возвращаемые значения

Функция возвращает прочтенные данные или FALSE в случае возникновения ошибки.

Внимание

Эта функция может возвращать как boolean FALSE , так и не-boolean значение, которое приводится к FALSE . За более подробной информацией обратитесь к разделу Булев тип . Используйте оператор === для проверки значения, возвращаемого этой функцией.

Ошибки

Будет сгенерирована ошибка уровня E_WARNING , если параметр filename не удается найти, параметр maxlength меньше нуля или поиск по смещению offset в потоке завершается неудачно.

Примеры

Пример #1 Получить и вывести исходный код домашней страницы вебсайта

$homepage = file_get_contents ("http://www.example.com/" );
echo $homepage ;
?>

Пример #2 Поиск файлов в include_path

// <= PHP 5
$file = file_get_contents ("./people.txt" , true );
// > PHP 5
$file = file_get_contents ("./people.txt" , FILE_USE_INCLUDE_PATH );
?>

Пример #3 Чтение секции файла

// Читаем 14 символов, начиная с 21 символа
$section = file_get_contents ("./people.txt" , NULL , NULL , 20 , 14 );
var_dump ($section );
?>

Результатом выполнения данного примера будет что-то подобное:

string(14) "lle Bjori Ro"

Пример #4 Использование потоковых контекстов

// Создаем поток
$opts = array(
"http" =>array(
"method" => "GET" ,
"header" => "Accept-language: en\r\n" .
"Cookie: foo=bar\r\n"
);

$context = stream_context_create ($opts );

// Открываем файл с помощью установленных выше HTTP-заголовков
$file = file_get_contents ("http://www.example.com/" , false , $context );
?>

Close_notify . PHP сообщит об этом как "SSL: Fatal Protocol Error" в тот момент, когда вы достигнете конца данных. Чтобы обойти это, вы должны установить error_reporting на уровень, исключающий E_WARNING. PHP версий 4.3.7 и старше умеет определять, что на стороне сервера находится проблемный IIS при открытии потока с помощью обертки https:// и не выводит предупреждение. Если вы используете fsockopen() для создания ssl:// сокета, вы сами отвечаете за определение и подавление этого предупреждения.