PHP delete images in unknown subdirectories

32

I'm looking for a way to delete images older than 30 days in randomly named folders.

I have the following directory structure on my server:

mainDirectory (folder)
  imagedeletescript.php (script)
  images (folder)
    uploads (folder)
      randomNamedFolder (folder)
      randomNamedFolder (folder)
      randomNamedFolder (folder)
      randomNamedFolder (folder)
      etc.

This is my imagedeletescript.php:

<?
$days = 30;
$dir = dirname ("/images/uploads");

$nofiles = 0;

    if ($handle = opendir($dir)) {
    while (( $file = readdir($handle)) !== false ) {
        if ( $file == '.' || $file == '..' || is_dir($dir.'/'.$file) ) {
            continue;
        }

        if ((time() - filemtime($dir.'/'.$file)) > ($days *86400)) {
            $nofiles++;
            unlink($dir.'/'.$file);
        }
    }
    closedir($handle);
    echo "Total files deleted: $nofiles \n";
}
?>

The script above will delete the randomNamedFolders that are older than 30 days in the uploads folder and that is not what I want.

How can I get the script to scan all the randomly named folders inside the uploads folder and delete all the images older than 30 days inside the randomly named folders?

420

Answer

Solution:

The best solution would be to implement a recursion. You can scan for all the directories and sub directories and even deeper directories.

<?php
     $days = 30,$deleted = 0;
     function delete_old_files($dir) {
       global $days,$deleted;
       if(!is_dir($dir)){
         return;
       }
       $files = preg_grep('/^([^.])/', scandir($dir));
       foreach($files as $file) {
         $path = $dir.'/'.$file;
         if(is_dir($path)){
            //the current file is a directory, re-scan it
            delete_old_files($path);
            continue;
         }
         if(time() - filemtime($path) > $days * 86400){
           unlink($file) ? ++$deleted : null;
         }
       }
       return $deleted;
     }
     //now call this function
     delete_old_files("/images/uploads");
109

Answer

Solution:

You have to replicate yourwhile loop inside mainloop, or you can use eitherscandir() orglob() in this way:

(...)    
while (( $file = readdir($handle)) !== false ) {
    if ( $file == '.' || $file == '..' || is_dir($dir.'/'.$file) ) {
        continue;
    }

    $curDir = "$dir/$file";
    foreach( scandir( $file ) as $rndFile ) {
        if ( $rndFile == '.' || $rndFile == '..' || is_dir("$curDir/$rndFile") ) continue;
        if ((time() - filemtime("$curDir/$rndFile")) > ($days *86400)) {
            $nofiles++;
            unlink($dir.'/'.$file);
        }
   }
}
(...)

People are also looking for solutions to the problem: Laravel 5: Password Reset - move bcrypt password to User.php model?

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.