Jaume Mal
Jaume Mal

Reputation: 658

echo Recursiveiteratoriterator output as key in array

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

Upvotes: 0

Views: 78

Answers (1)

iainn
iainn

Reputation: 17434

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);

Upvotes: 2

Related Questions