Получение даты изменения файла в PHP: обзор методов и примеры
Основные способы получения времени изменения файла в PHP
Наиболее эффективным и часто используемым решением является встроенная функция filemtime(). Она возвращает метку времени (Unix timestamp) последнего изменения содержимого файла. Пример:
$file = '/path/to/file.txt';
$timestamp = filemtime($file);
echo date('Y-m-d H:i:s', $timestamp);
Функция работает с локальными файлами и возвращает время изменения в соответствии с временной зоной сервера. Если файл не существует или недоступен, генерируется ошибка уровня E_WARNING и возвращается false.
Важно:
- Результат filemtime() может быть закэширован на уровне PHP (см. clearstatcache()).
- Для корректного отображения используйте date() или DateTime с нужным часовым поясом.
Как получить время изменения, используя функцию stat?
Функция stat() возвращает массив с информацией о файле, включая время последнего изменения (ключ 'mtime'), время доступа ('atime') и время изменения inode ('ctime'). Пример:
$stat = stat('file.txt');
if ($stat) {
$mtime = $stat['mtime'];
echo date('d.m.Y H:i', $mtime);
}
Проблема: stat() выполняет более тяжёлый системный вызов и возвращает много данных. Если нужен только mtime, лучше использовать filemtime. Типичная ошибка: не проверять возвращаемое значение (false при ошибке) вызывает warning.
Ошибка: stat(): Lstat failed for file.txt - файл не существует. Решение: предварительная проверка file_exists() или is_file().
Как узнать время последнего доступа к файлу?
Для получения времени последнего чтения файла используется fileatime(). Аналогично filemtime, но возвращает atime.
$atime = fileatime('data.log');
echo 'Последний доступ: ' . date('H:i:s', $atime);
На некоторых файловых системах (например, при монтировании с опцией noatime) обновление atime может быть отключено. В таких случаях fileatime() вернёт время создания или последнего изменения.
Как получить время изменения с помощью SplFileInfo?
Объектно-ориентированный способ - класс SplFileInfo. Метод getMTime() возвращает timestamp.
$file = new SplFileInfo('/var/log/nginx/access.log');
$mtime = $file->getMTime();
$datetime = (new DateTime())->setTimestamp($mtime);
echo $datetime->format('Y-m-d');
Ошибка: если объект создан для несуществующего файла, getMTime() вернёт false. Проверка через $file->isFile() обязательна.
Как отформатировать время изменения в произвольном виде?
После получения timestamp с помощью filemtime() можно использовать функцию date() или объект DateTime с методами форматирования. Пример с учётом часового пояса:
$tz = new DateTimeZone('Asia/Vladivostok');
$dt = new DateTime('@' . filemtime('config.ini'));
$dt->setTimezone($tz);
echo $dt->format('d.m.Y H:i:s');
Проблема: если не указать часовой пояс, будет использоваться системный. Это может привести к несоответствию между временем на сервере и отображаемым временем.
Как обработать ошибки при получении времени изменения?
Все перечисленные функции возвращают false при ошибке. Рекомендуется использовать условные проверки и, при необходимости, подавление ошибок с помощью оператора @:
$mtime = @filemtime('missing.txt');
if ($mtime === false) {
$error = error_get_last();
error_log('Ошибка получения mtime: ' . $error['message']);
}
Использование @ скрывает все ошибки, поэтому лучше комбинировать с проверкой результата и предварительной проверкой существования файла.
Расширенные примеры и нестандартные сценарии
Пример 1. Получение времени изменения всех файлов в директории и вывод в отсортированном виде:
$dir = '/path/to/dir';
$items = scandir($dir);
$files = [];
foreach ($items as $item) {
$fullpath = $dir . '/' . $item;
if (is_file($fullpath)) {
$files[$item] = filemtime($fullpath);
}
}
asort($files);
foreach ($files as $name => $mtime) {
echo $name . ' - ' . date('Y-m-d H:i', $mtime) . PHP_EOL;
}
file1.txt - 2025-03-20 14:30 file2.log - 2025-03-22 09:15 ...
Пример 2. Сравнение времени двух файлов для определения, какой новее:
$a = filemtime('a.txt');
$b = filemtime('b.txt');
if ($a > $b) {
echo 'a.txt новее';
} elseif ($a < $b) {
echo 'b.txt новее';
} else {
echo 'время одинаковое';
}
Пример 3. Использование функции clearstatcache() перед повторным вызовом filemtime для получения актуального времени (если файл был изменён прямо во время выполнения скрипта):
$file = 'dynamic.txt';
echo 'Первое чтение: ' . filemtime($file) . PHP_EOL;
sleep(2); // имитация ожидания
touch($file); // меняем время
clearstatcache();
echo 'После сброса кеша: ' . filemtime($file);
Первое чтение: 1742880000 После сброса кеша: 1742880012
Пример 4. Работа с FTP-файлами через stream wrapper (не все протоколы поддерживают filemtime):
$url = 'ftp://user:pass@example.com/pub/file.zip';
$mtime = filemtime($url);
if ($mtime !== false) {
echo 'FTP файл изменён: ' . date('c', $mtime);
} else {
echo 'Получение времени не поддерживается для данного FTP-сервера';
}
Пример 5. Преобразование Unix timestamp в разные форматы с учётом локали:
$ts = filemtime('data.csv');
setlocale(LC_TIME, 'ru_RU.UTF-8');
echo strftime('%A, %d %B %Y %H:%M', $ts); // если функция доступна
среда, 20 марта 2025 14:30
Пример 6. Получение времени создания файла (не путать с изменением) на некоторых системах (ctime). В Windows ctime - время создания, в Unix - время изменения inode. Пример для Windows:
$stat = stat('document.docx');
if (PHP_OS_FAMILY === 'Windows') {
$ctime = $stat['ctime'];
echo 'Создан: ' . date('d.m.Y', $ctime);
} else {
echo 'ctime на Unix означает изменение прав/метаданных';
}
Пример 7. Обработка исключений для файлов с ограниченными правами:
$file = '/etc/shadow'; // обычно нет доступа
$mtime = @filemtime($file);
if ($mtime === false) {
error_log('Недостаточно прав для чтения ' . $file);
} else {
echo $mtime;
}