🧱 Суть

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

  • чтение файлов
  • запись данных
  • создание и удаление файлов
  • работа с директориями
  • получение информации о файлах

Пример чтения файла:

$content = file_get_contents('data.txt');
 
echo $content;

Пример записи:

file_put_contents(
    'data.txt',
    'Hello PHP'
);

📦 Проблема

1. Данные не всегда хранятся в базе данных

Иногда приложению нужно работать с файлами:

  • конфигурации
  • логи
  • изображения
  • документы
  • временные данные

Например:

storage/
├── logs/
├── uploads/
└── cache/

2. Неправильная работа с файлами может привести к ошибкам

Проблемы:

  • файл не существует
  • нет прав доступа
  • неверный путь
  • повреждение данных при записи

3. Ручное управление потоками сложно

Работа напрямую через файловые дескрипторы требует больше кода:

$file = fopen('data.txt', 'r');
 
$data = fread($file, filesize('data.txt'));
 
fclose($file);

Для простых задач это избыточно.

✅ Решение

Использовать встроенные функции PHP:

  • file_get_contents() – чтение файла целиком
  • file_put_contents() – запись файла
  • fopen() / fclose() – работа с потоками
  • mkdir() – создание директорий
  • unlink() – удаление файлов
  • scandir() – просмотр содержимого папки

💻 Код

Пути к файлам

PHP работает с двумя типами путей:

Относительный путь

Относительно текущей директории:

file_get_contents('config.json');

Абсолютный путь

Полный путь в системе:

/home/project/config.json

__DIR__

Специальная константа, которая содержит путь к текущей папке.

Пример:

require __DIR__ . '/config.php';

Это надёжнее, чем:

require 'config.php';

Потому что текущая директория может отличаться.

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

file_get_contents()

Самый простой способ прочитать файл.

$text = file_get_contents('text.txt');
 
echo $text;

Результат:

Содержимое файла

Проверка существования файла

Перед чтением:

if (file_exists('text.txt')) {
    $text = file_get_contents('text.txt');
}

Получение информации о файле

echo filesize('text.txt');

Вернёт размер в байтах.

Другие функции:

filemtime('text.txt'); // время изменения
is_file('text.txt');   // является ли файлом
is_readable('text.txt'); // доступен ли для чтения

Запись файлов

file_put_contents()

Записывает данные в файл.

file_put_contents(
    'message.txt',
    'Hello PHP'
);

Если файла нет:

  • файл будет создан

Если файл есть:

  • содержимое будет заменено

Добавление в конец файла

По умолчанию:

file_put_contents(
    'log.txt',
    'New log'
);

перезаписывает файл.

Для добавления:

file_put_contents(
    'log.txt',
    'New log',
    FILE_APPEND
);

Добавление с блокировкой

Для безопасной записи:

file_put_contents(
    'log.txt',
    'Message',
    FILE_APPEND | LOCK_EX
);

LOCK_EX блокирует файл во время записи.

Работа через fopen()

fopen() открывает файл и возвращает ресурс.

$file = fopen(
    'data.txt',
    'r'
);

Режимы открытия файлов

РежимЗначение
rтолько чтение
wзапись с очисткой файла
aдобавление в конец
r+чтение и запись
w+чтение и запись с очисткой
a+чтение и добавление

Чтение через поток

Пример:

$file = fopen('data.txt', 'r');
 
$content = fread(
    $file,
    filesize('data.txt')
);
 
fclose($file);

Построчное чтение

Для больших файлов:

$file = fopen('log.txt', 'r');
 
while (($line = fgets($file)) !== false) {
    echo $line;
}
 
fclose($file);

Преимущество:

  • файл не загружается целиком в память

Удаление файлов

Используется:

unlink('old.txt');

Пример:

if (file_exists('old.txt')) {
    unlink('old.txt');
}

Работа с директориями

Создание папки

mkdir('uploads');

Создание вложенных папок:

mkdir(
    'storage/images',
    recursive: true
);

Проверка директории

is_dir('storage');

Получение содержимого папки

$files = scandir('uploads');
 
print_r($files);

Результат:

[
 ".",
 "..",
 "image.jpg"
]

Удаление директории

rmdir('empty-folder');

Важно:
rmdir() удаляет только пустые папки.

Загрузка файлов

Обычно используется массив:

$_FILES

Пример:

$_FILES['avatar'];

Содержит:

[
    'name',
    'type',
    'tmp_name',
    'size',
    'error'
]

Перемещение загруженного файла:

move_uploaded_file(
    $_FILES['avatar']['tmp_name'],
    'uploads/avatar.jpg'
);

Безопасность при работе с файлами

Проверять расширение

Плохо:

move_uploaded_file(
    $tmp,
    "uploads/" . $name
);

Пользователь может загрузить:

script.php

Лучше:

$allowed = [
    'jpg',
    'png'
];

Не использовать имя файла пользователя напрямую

Опасно:

uploads/photo.jpg

Лучше:

uploads/65f3a91.jpg

Например через:

uniqid();

Проверять MIME-тип

Расширение можно подделать:

image.jpg

но внутри может быть PHP-код.

Используют:

mime_content_type();

Типичная структура хранения файлов

В проектах часто:

project/

├── public/

├── storage/
│   ├── logs/
│   ├── uploads/
│   └── cache/

└── src/

Работа с JSON-файлами

Частый вариант хранения настроек.

Чтение:

$data = file_get_contents(
    'config.json'
);
 
$config = json_decode(
    $data,
    true
);

Запись:

$json = json_encode(
    $config,
    JSON_PRETTY_PRINT
);
 
file_put_contents(
    'config.json',
    $json
);

Частые ошибки

Не проверять существование файла

Плохо:

$data = file_get_contents(
    'config.json'
);

Лучше:

if (file_exists('config.json')) {
    $data = file_get_contents('config.json');
}

Хранить пользовательские файлы без ограничений

Опасно:

uploads/

без:

  • проверки типа
  • ограничения размера
  • генерации имени

Использовать абсолютные пути вручную

Плохо:

require '/var/www/project/file.php';

Лучше:

require __DIR__ . '/file.php';

🎯 Вывод

  • PHP имеет встроенные инструменты для работы с файлами и папками
  • file_get_contents() и file_put_contents() подходят для простых операций
  • fopen() используется для работы с потоками и большими файлами
  • __DIR__ помогает создавать надёжные пути
  • mkdir(), scandir(), unlink() используются для управления файловой системой
  • загружаемые файлы всегда нужно проверять
  • пользовательские данные нельзя использовать напрямую в путях
  • в современных приложениях файлы обычно хранятся отдельно в storage

🔗 Связано