fopen()
Функция fopen() — встроенная PHP-функция для открытия файлов и URL. Возвращает файловый указатель для чтения и записи.
Что такое функция fopen()?
Функция fopen() — это встроенная PHP-функция, которая открывает файл (или URL) и возвращает файловый указатель — дескриптор ресурса, который затем передаётся таким функциям, как fread(), fwrite(), fgets() и fclose(), для фактического чтения, записи и закрытия потока. В случае неудачи возвращает false и выдаёт предупреждение E_WARNING.
Практически каждая операция с файлом в PHP, которая выполняет инкрементное чтение или запись, начинается с fopen(). (Для разовых операций чтения и записи обычно используют file_get_contents() и file_put_contents() — см. раздел Когда не следует использовать fopen().)
Синтаксис
fopen(string $filename, string $mode, bool $use_include_path = false, $context = null): resource|false| Параметр | Описание |
|---|---|
$filename | Путь к файлу или URL (например, https://…, php://stdin), если включены обёртки потоков. |
$mode | Режим открытия файла — чтение, запись, добавление и т. д. См. таблицу ниже. |
$use_include_path | Если true, PHP также ищет файл в include_path. |
$context | Необязательный контекст потока, созданный с помощью stream_context_create(). |
При успехе возвращает ресурс-указатель на файл, при ошибке — false.
Режимы fopen()
Аргумент $mode — та часть, в которой чаще всего допускают ошибки. Он определяет, открывается ли файл для чтения, записи или для обоих действий, где начинается внутренний указатель, и будет ли файл усечён или должен уже существовать.
| Режим | Чтение | Запись | Указатель начинается с | Усечение? | Если файл отсутствует |
|---|---|---|---|---|---|
r | да | нет | начала | нет | предупреждение, возвращает false |
r+ | да | да | начала | нет | предупреждение, возвращает false |
w | нет | да | начала | да | создаёт файл |
w+ | да | да | начала | да | создаёт файл |
a | нет | да | конца | нет | создаёт файл |
a+ | да | да | конца (запись всегда добавляется) | нет | создаёт файл |
x | нет | да | начала | нет | создаёт файл; ошибка, если уже существует |
x+ | да | да | начала | нет | создаёт файл; ошибка, если уже существует |
К любому режиму можно добавить b (двоичный, например 'rb') или t (текстовый). Всегда используйте 'b' для нетекстовых файлов, таких как изображения или исполняемые файлы — в Windows текстовый режим незаметно преобразует символы конца строки и повреждает двоичные данные. В Unix оба режима идентичны, поэтому 'b' является безопасным вариантом по умолчанию.
Базовый пример: чтение файла
Откройте файл в режиме чтения, прочитайте его содержимое, затем закройте. Всегда проверяйте возвращаемое значение перед использованием дескриптора, и всегда вызывайте fclose() по завершении, чтобы операционная система могла освободить дескриптор.
<?php
$filename = 'myfile.txt';
$file = fopen($filename, 'r');
if ($file === false) {
echo "Unable to open file!";
} else {
echo fread($file, filesize($filename));
fclose($file);
}Мы открываем myfile.txt в режиме «только чтение» и проверяем дескриптор строгим сравнением === false — это важно, поскольку корректный ресурс является истинным значением, но некоторые не-ошибочные значения тоже истинны, и нестрогие проверки могут создать проблемы в дальнейшем.
Запись в файл
Открытие с 'w' создаёт файл, если он не существует, и усекает его до нулевой длины, если существует. Используйте 'a', когда нужно добавить данные в конец без удаления имеющегося содержимого (удобно для лог-файлов).
<?php
$file = fopen('log.txt', 'w'); // create / overwrite
fwrite($file, "First line\n");
fwrite($file, "Second line\n");
fclose($file);
$file = fopen('log.txt', 'a'); // append, keep existing content
fwrite($file, "Appended later\n");
fclose($file);
echo file_get_contents('log.txt');Это выводит все три строки, поскольку 'a' добавил данные в файл, а не заменил его. Смотрите fwrite() для записи и feof() для определения конца файла в цикле.
Чтение построчно
Для больших файлов не читайте всё содержимое в память сразу. Используйте fopen() вместе с fgets() и feof() для построчного чтения потока:
<?php
$file = fopen('myfile.txt', 'r');
if ($file) {
while (!feof($file)) {
$line = fgets($file);
if ($line !== false) {
echo $line;
}
}
fclose($file);
}Частые ошибки
- Забыть проверить
false. Если путь неверен или доступ запрещён,fopen()возвращаетfalseи выдаёт предупреждение. Вызовfread()сfalseприводит кTypeErrorв PHP 8+. - Не закрыть дескриптор. Открытые дескрипторы — ограниченный ресурс; их утечка в долго работающем процессе рано или поздно исчерпает лимит ОС. Всегда вызывайте
fclose(), в идеале в блокеfinally. - Неправильный режим. Использование
'w'вместо'r'тихо затирает файл. Используйте'x', если хотите, чтобы создание файла завершилось ошибкой при его существовании. - Относительные пути. Они разрешаются относительно текущего рабочего каталога скрипта, что не всегда совпадает с ожиданиями. Предпочитайте абсолютные пути или
__DIR__ . '/file.txt'.
Когда не следует использовать fopen()
Если вам просто нужно прочитать весь файл как string или записать string в файл за один вызов, пропустите связку открытие/чтение/закрытие:
| Цель | Более простая функция |
|---|---|
| Прочитать весь файл в string | file_get_contents() |
| Записать string в файл за один вызов | file_put_contents() |
| Прочитать файл в array строк | file() |
| Передать файл прямо в вывод | readfile() |
Прибегайте к fopen(), когда нужен детальный инкрементный контроль — чтение больших файлов блоками, добавление в лог или работа с нефайловыми потоками, такими как php://stdin.
Заключение
fopen() — это основа низкоуровневой работы с файлами в PHP: она возвращает файловый указатель, который используется для чтения с помощью fread() / fgets(), записи с помощью fwrite(), и всегда освобождается через fclose(). Выберите правильный режим, проверьте возвращаемое значение, закройте дескриптор — и остальные функции работы с файлами в PHP будут следовать естественным образом.