Курс PHP для начинающих - с нуля до джуниора за 2 месяца. Жми!
base14 8

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

Курс PHP для начинающих
Внимание! Данный урок устарел!
Переходите к новому уроку "Учимся работать с файлами в PHP".

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

Курс PHP для начинающих

Функции чтения и записи файлов

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

Любой сеанс манипулирования файлом может состоять из описанных ниже шагов:

  1. Открыть файл для чтения-записи.

  2. Выполнить операцию чтения в файле.

  3. Провести необходимые операции с содержимым файла.

  4. Записать результаты в файл (если нужно).

  5. Закрыть файл.

Для выполнения каждого из этих шагов предусмотрена соответствующая функция работы с файловой системой языка PHP.

Операция открытия файла

Для открытия файлов используется функция fopen(). Результат выполнения функции fopen() необходимо присваивать переменной. Следует учитывать, что функция fopen() в результате успешного выполнения возвращает не целое число, а строку, в которой приведены данные "Resource id #n", где n - номер открытого в настоящее время потока. Не следует пытаться проконтролировать успешное выполнение операции открытия файла с помощью вызовов функции is_int() или is_numeric(). Вместо этого следует использовать функцию die().

Если операция открытия файла прошла успешно, интерпретатор PHP возвращает идентификатор ресурса, который требуется для осуществления дальнейших операций, таких как fread или fwrite. В противном случае будет получено значение false.

Код PHP
$fd = fopen($filename, "r+") or die("Файл нельзя открыть");

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

  • Режим только чтения ("r").

  • Режим чтения и записи, применяемый, если файл уже существует ("r+"). Запись осуществляется в начало файла; а если файл считывается как строка, после чего эта строка редактируется и снова выводится в файл, то фактически происходит запись обновленного файла с сохранением его первоначального содержимого.

  • Режим только записи ("w"), в котором перед выполнением каких-либо операций записи создается файл с указанным именем, если этот файл еще не существует, и стирается содержимое указанного файла, если он существует! Данный режим не может использоваться для чтения файла; он предназначен только для записи.

  • Режим записи и чтения, применяемый, даже если файл еще не существует ("w+"), предусматривает создание файла с указанным именем (при условии, что он не существует) и удаление до начала выполнения операций записи содержимого указанного файла!

  • Режим только записи, применяемый для дополнения файла, независимо от того, существует ли файл или нет ("a").

  • Режим записи и чтения, применяемый для дополнения файла, независимо от того, существует ли файл или нет ("а+"). Если файл считывается как строка, после чего эта строка редактируется и снова выводится в файл, то фактически происходит запись обновленного файла с сохранением первоначального содержимого файла.

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

Для работы с файлами предусмотрена возможность открывать несколько типов соединений и использовать средства доступа, включая HTTP, HTTPS, FTP, FTPS, стандартный ввод-вывод, и др.

При использовании функции fopen() для работы по протоколу HTTP предпринимается попытка открыть соединение по протоколу HTTP 1.0 для обработки файла такого типа, который обычно обрабатывается веб-сервером (таким как файл HTML, PHP, ASP и т.д.). По существу, интерпретатор PHP вынуждает веб-сервер действовать так, как будто переданный ему запрос поступил из обычного веб-браузера, применяемого для просмотра Интернета, а не был получен с помощью операции открытия файла:

Код PHP
$fd = fopen("https://www.mysite.com/index.php/", "r")
	or die("Файл нельзя открыть");

Следует помнить, что с формальной точки зрения URL без заключительного символа косой черты рассматривается как имеющий неправильную структуру, но в большинстве веб-серверов при получении параметра адреса, не соответствующего этому требованию, автоматически осуществляется замена URL такой же строкой с заключительным символом косой черты и предпринимается попытка перенаправить запрос по полученному адресу.

При использовании функции fopen() для работы по протоколу FTP предпринимается попытка установить соединение FTP с удаленным сервером от имени FTP-клиента. Этот вариант применения функции fopen() является более сложным, поскольку в данном случае, кроме имени хоста и пути к файлу, приходится также указывать имя пользователя и пароль FTP, как показано ниже:

Код PHP
$fd = fopen("ftp://username:password@www.mysite.com/index.php/", "r")
	or die("Файл нельзя открыть");

Этот способ доступа осуществляется успешно только при условии, что используемый FTP-сервер поддерживает пассивный режим. Кроме того, открытие файла FTP может осуществляться только для чтения или записи, но не для выполнения той и другой операции, а операции записи должны использоваться только для создания новых файлов, а не для дополнения существующих.

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

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

Код PHP
$fd = fopen("d:\\file.txt", "r")
	or die("Файл нельзя открыть");

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

Операции чтения файла

Функция fread() принимает в качестве параметров идентификатор указателя файла и размер файла в байтах. Если указанный размер файла не является достаточным для чтения всего файла, то в работе программы возникают загадочные нарушения (исключением является такая ситуация, когда меньший размер файла задается намеренно; такой способ доступа может применяться при чтении огромных файлов в виде отдельных фрагментов). Поэтому, если нет оснований для применения другого подхода (например, обусловленного необходимостью чтения колоссального, неуправляемого файла), то лучше всего предоставить возможность заполнить значение параметра размера файла самому интерпретатору PHP, используя функцию filesize() с указанием в качестве параметра имени файла (или переменной с именем файла), как в следующем примере:

Код PHP
$fr = fread($fd, filesize($filename));

При использовании указанной конструкции часто возникает ошибка, состоящая в том, что применяется вызов filesize($fd), а не filesize($filename).

Функция fread() исключительно полезна, поскольку позволяет преобразовать любой файл в строку, с которой в дальнейшем могут осуществляться манипуляции с помощью широкого перечня полезных строковых функций PHP. К тому же любую строку можно преобразовать в массив с использованием таких функций, как file() или explode(), что позволяет получить доступ к большому арсеналу функций манипулирования массивами языка PHP.

Начиная с версии PHP 4.3.0 пользователям предоставлен доступ к новой функции — file_get_contents(). Эта функция возвращает все содержимое файла в виде строки и обладает возможностями функции fopen(). Применение функции file_get_contents() равносильно применению функций fopen() и fread().

Если требуется и выполнять чтение, и применять к файлу операции построчной обработки, то вместо функции fread() можно использовать функцию fgets(). Начиная с версии PHP 4.2.0 по умолчанию предусмотрено, что функция возвращает по 1024 байта в расчете на каждую строку, если в качестве второго параметра функции fgets() не задана длина строки.

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

Операции записи файла

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

Функция fputs() полностью идентична функции fwrite(), но fputs() имеет имя в стиле функций языка C.

Следует помнить, что открытие файла в режиме w или w+ приводит к полному и окончательному уничтожению всего содержимого файла. Указанные режимы предназначены только для перезаписи файлов, очищенных от прежнего содержимого. Если же требуется обеспечить запись в начале или в конце файла, то следует использовать соответственно режим r+ или a+.

Операции закрытия файла

Операция закрытия файла является несложной:

Код PHP
fclose($fd);

В отличие от функции fopen() результат выполнения функции fclose() не требуется присваивать переменной. На первый взгляд может показаться, что применение в сценарии операций закрытия файла является для программиста пустой тратой времени, но количество применимых дескрипторов файлов в системе ограничено, поэтому существует вероятность того, что доступные дескрипторы файлов будут исчерпаны, если ненужные файлы останутся открытыми. С другой стороны, интерпретатор PHP закрывает все открытые файлы после завершения сценария.

Ниже показан полный пример чтения и записи файла из текущей файловой системы:

Код PHP
echo '<b>Чтение файла: </b><br>';

$filename = $_SERVER['PHP_SELF'];
$fd = fopen($filename, "r") or die("Файл нельзя открыть");

$page_contents = '';
while ($new_text = fread($fd, 100)) 
{
	$page_contents .= $new_text;
}
	
echo '<pre>'.htmlentities($page_contents).'</pre>';
fclose($fd);

echo '<b>Запись в файл</b><br><br>';
$fd = fopen($filename, "w+") or die("Файл нельзя открыть");
fwrite ($fd, 'Hello, world!');
fclose($fd);
Чтение из файла

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

Запись в файл

Функция feof

Функция feof принимает в качестве параметра дескриптор файла и проверяет, не достигнут ли конец указанного файла. В основном эта функция используется в цикле while, в котором применяются аналогичные операции обработки к каждой строке файла, как в следующем примере:

Код PHP
while (!feof($fd)) 
{
	$line = fgets($fd, 4096); 
	echo $line;
}

Функция file_exists

функция file_exists — это простая функция, к использованию которой приходится прибегать очень часто, если для доступа к данным применяются функции файловой системы. Эта функция просто проверяет наличие в локальной файловой системе файла с указанным именем, как показано ниже:

Код PHP
if (file_exists($filename))
{
	$fd = fopen($filename, "w+");
	fwrite ($fd, 'Hello, world!');
}

Функция возвращает значение true, если файл существует, а если файл не найден, возвращает значение false. Результаты проверки сохраняются в кэше, который может быть очищен с помощью функции clearstatcache().

Обработка форм
Cookie-файлы и сеансы

Комментарии (0)

Результаты поиска по запросу

Система Orphus