0

My weak shared web host doesn't support cron or perl and I often need to delete thousands of .jpg images from certain folders. The images are uploaded from webcams. I'm wondering if there is a simple app out there that can find all .jpg images recursively and delete them.

I need to be able to target only images in the following date format : 2011-10-19_00-29-06.jpg ... and only images older than 48 hours.

Apache 2.2.20 DirectAdmin 1.39.2 MySQL 5.1.57 Php 5.2.17

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Wes
  • 79
  • 2
  • 10
  • 1
    If you have DirectAdmin it's possible that you have shell, so you can delete all your jpgs with one command `find /dirname_where_jpgs_located -iname '\*.jp?eg' -exec rm -rf {} \;` –  Oct 18 '11 at 17:48
  • thanks for the quick reply... the host does not allow ssh :( Do you know of a php app with a gui that makes this process easy for a non programmer? Thanks for any tips. – Wes Oct 18 '11 at 17:55
  • You will be given a tonn of advices, so you don't need any gui :)) –  Oct 18 '11 at 17:59
  • possible duplicate of http://stackoverflow.com/search?q=recursively+delete+files+php – Gordon Oct 18 '11 at 18:22
  • try this http://www.webdeveloper.com/forum/showthread.php?t=164845 – echo_Me Oct 18 '11 at 18:41

4 Answers4

1

@user427687, Do you mean all the picture format 2011***.jpg? if so, may be my code would work.

<?php
  $path = dirname(__FILE__).'/filepath';
  if ($handle = opendir($path)) {
    while (false !== ($file = readdir($handle))) {
        if ((time()-filectime($path.'/'.$file)) < 86400*2) {
          if (preg_match('/\2011(.*?).jpg$/i', $file)) {
            unlink($path.'/'.$file);
          }
          if (preg_match('/\2011(.*?).jpeg$/i', $file)) {
            unlink($path.'/'.$file);
          }
        }
    }
  }
?>
Giberno
  • 1,323
  • 4
  • 17
  • 31
0

or just with php:

<?php

$last_2_days_in_seconds = 3600 * 48;

foreach (glob("*.jpg") as $filename) {
  if((time() - fileatime($filename)) > $last_2_days_in_seconds && preg_match('/^2011/', $filename)) unlink($filename);
}
?>
  • 1
    atime's not the best thing. theoretically all those images could've been viewed in the last 10 minutes, in which case NONE would get deleted. – Marc B Oct 18 '11 at 17:59
  • you want to say that file access time will not be changed? how that can be? can you give an example? I'm interested. –  Oct 18 '11 at 18:00
  • 2
    atime is the last time someone accessed the file, or changed its metadata. simply opening/viewing the jpg in an image viewer will updates its atime, since it's been "accessed". ctime and mtime are more reliable, as they only change if someone about the file is changed changed (ctime, for inode-data) or the file's contents are changed (mtime). – Marc B Oct 18 '11 at 18:09
  • Thanks for the quick response.... And if I want to target only .jpg images that have the text "2011" in the file name? example: 2011-10-18_16-07-48.jpg Thanks again – Wes Oct 18 '11 at 18:12
  • but it's not a problem at all to change file`a`time to file`m`time or use (stat)[http://php.net/stat] to check everything you want, it's just the way I think author wanted to do his task –  Oct 18 '11 at 18:15
  • I've improved my first answer to be suitable for your task with file names. –  Oct 18 '11 at 18:17
  • Many thanks!.... I tried created and uploaded the php file and gave it 777 permissions... it give me this error when I visit the url of the php file in the browser: Warning: unlink(2011-10-16_02-06-58.jpg) [function.unlink]: Permission denied in /home/xxxx/domains/xxxx.com/public_html/xxx/xxx/test.php on line 6 Thanks for any suggestions. – Wes Oct 18 '11 at 18:58
  • you just don't have permissions, check how this file was created, etc. maybe your local user has this privileges but www has no.. –  Oct 18 '11 at 19:00
0

A simple naiive version:

$yesterday = date('Y-m-d', strtotime('yesterday')); // 2011-10-17
$day_before = date('Y-m-d', strtotime('2 days ago')); // 2011-10-16

$images = glob('*.jpg');

foreach($images as $img) {
    if (strpos($img, $yesterday) === 0) || (strpos($img, $day_before) === 0)) {
        continue;
    }
    unlink($img);
}

This will delete all files which are date-stamped 3 days or older, by checking if the file is date stamped yesterday or day-before-yesterday. But it will also delete all files created today.

A better version would be:

$images = glob("*.jpg");
foreach ($images as $img) {
     $ctime = filectime($img);
     if ($ctime < (time() - 86400 * 2)) {
         unlink($img);
     }
}

This version checks the actual last-modified time on the file, and deletes anything older than 48 hours. It will be slower, however, as the stat() call performed by filectime() will be a non-cheap call.

Marc B
  • 356,200
  • 43
  • 426
  • 500
  • Marc, thanks for the quick response.... And if I want to target only .jpg images that have the text "2011" in the file name? example: 2011-10-18_16-07-48.jpg Thanks again – Wes Oct 18 '11 at 18:10
0

Something like this should get you started:

class MyRecursiveFilterIterator extends RecursiveFilterIterator {
    const EXT = '.jpg';
    public function accept() {
        // code that checks the extension and the modified date
        return $this->current()->getFilename() ...
    }
}

$dirItr    = new RecursiveDirectoryIterator('/sample/path');
$filterItr = new MyRecursiveFilterIterator($dirItr);
$itr       = new RecursiveIteratorIterator($filterItr, RecursiveIteratorIterator::SELF_FIRST);

// to iterate the list
foreach ($itr as $filePath => $fileInfo) {
    echo $fileInfo->getFilename() . PHP_EOL;
}
JRL
  • 76,767
  • 18
  • 98
  • 146