Gerard Brull
Gerard Brull

Reputation: 1062

filemtime "warning stat failed for"

I already read it so many questions and answers about it but I can't still solve my problem...

I'm trying to create a function that deletes all the files with "xml" or "xsl" extension that has been created one day ago. But I'm getting this warning on each file I have:

Warning: filemtime() [function.filemtime]: stat failed for post_1003463425.xml in /home/u188867248/public_html/ampc/library.php on line 44

All the files of this directory have the same structure name "post_ + randomNum + .xml" (example: post_1003463425.xml or post_1456463425.xsl). So I think it's not an encoded problem (like I saw in other questions).

The code of my function is this:

 function deleteOldFiles(){
    if ($handle = opendir('./xml')) {
        while (false !== ($file = readdir($handle))) { 

            if(preg_match("/^.*\.(xml|xsl)$/i", $file)){

                $filelastmodified = filemtime($file);

                if ( (time()-$filelastmodified ) > 24*3600){
                    unlink($file);
                }
            }
        }
        closedir($handle); 
    }
}

Thanks for your help :)

Upvotes: 44

Views: 155514

Answers (5)

Colleiflower
Colleiflower

Reputation: 15

Another solution to this problem that I had discovered after a week of on-and-off debugging is that the process running PHP may not have appropriate permissions to access the file. If you're sure the file path exists, make sure the permissions for it are appropriate as well.

Upvotes: 0

Peter H
Peter H

Reputation: 21

in my case it was not related to the path or filename. If filemtime(), fileatime() or filectime() don't work, try stat().

$filedate = date_create(date("Y-m-d", filectime($file)));

becomes

$stat = stat($directory.$file);
$filedate = date_create(date("Y-m-d", $stat['ctime']));

that worked for me.

Complete snippet for deleting files by number of days:

$directory = $_SERVER['DOCUMENT_ROOT'].'/directory/';
$files = array_slice(scandir($directory), 2);
foreach($files as $file)
{
    $extension      = substr($file, -3, 3); 
    if ($extension == 'jpg') // in case you only want specific files deleted
    {
        $stat = stat($directory.$file);
        $filedate = date_create(date("Y-m-d", $stat['ctime']));
        $today = date_create(date("Y-m-d"));
        $days = date_diff($filedate, $today, true);
        if ($days->days > 1) 
        { 
            unlink($directory.$file);
        }
    } 
}

Upvotes: 2

lufc
lufc

Reputation: 2040

Shorter version for those who like short code:

// usage: deleteOldFiles("./xml", "xml,xsl", 24 * 3600)


function deleteOldFiles($dir, $patterns = "*", int $timeout = 3600) {

    // $dir is directory, $patterns is file types e.g. "txt,xls", $timeout is max age

    foreach (glob($dir."/*"."{{$patterns}}",GLOB_BRACE) as $f) { 

        if (is_writable($f) && filemtime($f) < (time() - $timeout))
            unlink($f);

    }

}

Upvotes: 0

Andrew
Andrew

Reputation: 20091

For me the filename involved was appended with a querystring, which this function didn't like.

$path = 'path/to/my/file.js?v=2'

Solution was to chop that off first:

$path = preg_replace('/\?v=[\d]+$/', '', $path);
$fileTime = filemtime($path);

Upvotes: 1

Somy A
Somy A

Reputation: 1712

I think the problem is the realpath of the file. For example your script is working on './', your file is inside the directory './xml'. So better check if the file exists or not, before you get filemtime or unlink it:

  function deleteOldFiles(){
    if ($handle = opendir('./xml')) {
        while (false !== ($file = readdir($handle))) { 

            if(preg_match("/^.*\.(xml|xsl)$/i", $file)){
              $fpath = 'xml/'.$file;
              if (file_exists($fpath)) {
                $filelastmodified = filemtime($fpath);

                if ( (time() - $filelastmodified ) > 24*3600){
                    unlink($fpath);
                }
              }
            }
        }
        closedir($handle); 
    }
  }

Upvotes: 52

Related Questions