0

I am writing a script that recursively gets all files in server which have been modified before a particular time along their modification dates, orders them by modification date and prints them.

The code, without ordering works fine:

<?php
try {
    $rootdir = $_SERVER['DOCUMENT_ROOT'];
    $raw = new RecursiveDirectoryIterator($rootdir);
    $cooked = array();
    $yesdate = strtotime("-5 year");
    foreach(new RecursiveIteratorIterator($raw) as $file) {
        if (filemtime($file) >= $yesdate) {
            $cooked[] = $file;
        }
    } 
    foreach($cooked as $file) {
        echo date("F d Y H:i:s.", filemtime($file)) . $file . ' ' . '<br />';
    }    
} catch (Exception $ex) {
    echo $ex->getMessage();
}

But once I use $file as array key and filemtime($file) as value, order and attempt to loop and echo, I get 200 code but the page comes out white, can't figure out why:

<?php
try {
    $rootdir = $_SERVER['DOCUMENT_ROOT'];
    $raw = new RecursiveDirectoryIterator($rootdir);
    $cooked = array();
    $yesdate = strtotime("-5 year");
    foreach(new RecursiveIteratorIterator($raw) as $file) {
        if (filemtime($file) >= $yesdate) {
            $cooked[$file] = filemtime($file); // $file as key , mod datetime as value 
        }
    } 
    asort($cooked); // Sort
    foreach($cooked as $key => $value) {
        echo $key; // for example
        echo $value;
        //echo date("F d Y H:i:s.", filemtime($file)) . $file . ' ' . '<br />';
    }    
} catch (Exception $ex) {
    echo $ex->getMessage();
}

What is wrong with this code?

Thank you

1 Answer 1

2

If look at the error log for your second example, you'll probably see a lot of entries like this

PHP Warning: Illegal offset type in /home/... on line 9
PHP Stack trace:
PHP 1. {main}() /home/...

Line 9 is where you're building up your array elements:

$cooked[$file] = filemtime($file);

The problem is that $file here isn't a string, it's an instance of SplFileInfo. This works in your first example because that class implements __toString, which means filemtime can deal with it. But using it directly as an array key won't work.

The easy fix is to manually cast it to a string when adding the element:

$cooked[(string) $file] = filemtime($file);

An alternative (better?) option would be to use the second constructor argument to RecursiveDirectoryIterator, which tells it to just give you filenames in the first place:

$raw = new RecursiveDirectoryIterator($rootdir, FilesystemIterator::CURRENT_AS_PATHNAME);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.