3

http://php.net/manual/en/class.filesystemiterator.php

I noticed that FilesystemIterator returns the files ordered by name. Can anyone confirm this is true and it always happens? I haven't found anything in the docs.

Another question, is there any way to get the files ordered by the creation time on the disk? getCTime() seems to return the change time so I can't use it with usort()

Elfy
  • 1,265
  • 5
  • 14
  • 32

4 Answers4

3

I did some digging into PHP internals.

If I am not mistaken, the __construct method of FileSystemIterator ends up using the VCWD_OPENDIR C macro : https://github.com/php/php-src/blob/2f443acad19816e29b0c944426238d9f23af1ae2/main/streams/plain_wrapper.c#L908

This is a macro to the C Function opendir().

By looking at the documentation of that function, I can't see anything that would allow to define any kind of order : http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html

Knowing that, I would assume that the order is not enforced and could vary depending on the type of filesystem used (fat32, ntfs, etc.).

Therefore, If I were you - to be safe - I would implement a PHP function that would order them the way I want.

For your 2nd question, check : PHP: how can I get file creation date?

Community
  • 1
  • 1
alfallouji
  • 1,140
  • 8
  • 12
  • *I can't see anything that would allow to define any kind of order* You don't even have to look at the function and you also won't find anything, because an iterator never holds all data at once! it's called an "iterator" and it's lazy in data handling, so it only holds 1 item at a time – Rizier123 Mar 17 '15 at 16:55
  • Rizier123: But the files have to come from somewhere and there has to be an order at some level. Nothing is random inside a computer :/ Thank you for your answer alfallouji :) – Elfy Mar 17 '15 at 17:15
  • @Elfy If you want to know how php does this you would have to look into the "communication" between internal and external iterators – Rizier123 Mar 17 '15 at 17:50
  • @Elfy An iterator indeed takes the data 1 item at a time, however this does not mean that the iterator does not do it in a specific order and/or that there is no way to control that order. For example, you can control the order of an iterator of a db resultset by specifying an `order` statement within your sql query. – alfallouji Mar 18 '15 at 08:17
2

You have to sort them outside of the FilesystemIterator as it only iterates.

Here's an example:

$files = array();
$dir = new DirectoryIterator('.');
foreach ($dir as $fileinfo) {     
   $files[$fileinfo->getMTime()][] = $fileinfo->getFilename();
}

ksort($files);
sleepless_in_seattle
  • 1,912
  • 2
  • 20
  • 33
2

In fact, the order can be random. So, you have to sort arbitrarily. To sort alphabetically, use this simple construction:

$files = iterator_to_array(new RecursiveDirectoryIterator('.', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS), true);
ksort($files);

Set flags as needed.

William
  • 106
  • 4
1

I noticed that FilesystemIterator returns the files ordered by name. Can anyone confirm this is true and it always happens? I haven't found anything in the docs.

You can't sort data which comes from an Iterator. Why? Because an Iterator is lazy with the data handling, that means the iterator only knows about 1 item at the time.

So the Iterator doesn't sort the files in any way and you can't sort the data directly from an iterator, you would have to save it into an array or so to be able to sort the data.

Another question, is there any way to get the files ordered by the creation time on the disk?

usort() is a good idea, but not with DirectoryIterator::getCTime(), because this is a method of the iterator. But you can use: filemtime() (Just be aware of that the function is cached!)

Rizier123
  • 56,111
  • 16
  • 85
  • 130