Кэш на диске структурирован следующим образом: в этом примере имена подкаталогов представляют собой хэши:
Код: Выделить всё
/path/to/cache
-> 7a68fba56
----> some_file.jpg
----> another_file.png
----> some_stuff.svg
-> b12a43293
----> some_picture.webp
----> selfie.avif
----> afile.png
----> profit.jpg
----> A-team-crew.jpg
-> 0fe2ba852
----> ...
Код: Выделить всё
class myGarbageCollector
{
protected $timeout = 1209600; // about 2 weeks: 60x60x24x14
public function __construct(array $directories)
{
foreach ($directories as $directory) {
$this->deleteStaleFiles($directory);
}
}
private function deleteStaleFiles($path)
{
$now = time();
$dirs = new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($dirs, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file) {
$filepath = $file->getRealPath();
// Delete file if:
// * It's an image
// * It's a dead link
// * It's last accessed more than $timeout seconds ago
if ($file->isFile()
&& strpos(mime_content_type($filepath), 'image/') === 0
&& (
($file->isLink() && !$file->isReadable()) || ($now - $file->getATime()) > $this->timeout)
) {
unlink($filepath);
}
// Remove empty directories too.
if ($file->isDir()) {
// Need to somehow count the files in this subdir and
// rmdir($filepath) if there are zero files inside
}
}
}
}
Я ценю, что при любой данной очистке он может удалить все файлы в подкаталоге, и к тому времени это «прошел мимо» каталога, поэтому не удалит его. Это нормально, потому что при следующей очистке (при условии, что в этот подкаталог не было добавлено больше файлов) он удалит пустой каталог. Я не возражаю против этого (хотя, если удаление подкаталога можно выполнить за один проход, это даже лучше).
Может быть, я мог бы создать новый экземпляр DirectoryIterator(), используя текущий путь? Но это, конечно, сводит на нет смысл рекурсивного итератора?
Могу ли я рассматривать это как две отдельные вещи и использовать обычный DirectoryIterator для обхода подкаталогов непосредственно под кешем, а затем для каждого из них создавать новый DirectoryIterator для проверки файлов внутри него?
Я не женат на итераторах, поэтому, если что-то вроде scandir() или glob() будет более эффективным, тогда это круто. В кеше могут быть тысячи файлов, поэтому я ищу наиболее эффективное решение.
Подробнее здесь: https://stackoverflow.com/questions/798 ... collection
Мобильная версия