List directory contents by modified date in php
At home we have quite a large collection of movies that have been collaborated over the years and are all stored on a central server. Every movie is stored in a unique folder along with some backdrop images and a xml file which stores information such as the movie title, description, production year and our own custom reviews. I wrote a C# application which allowed everybody to view all of this information easily and everything works well. But it didn't seem very helpful having a nice list of all the movies and their data unless you could view them in a newest to oldest order. I first implemented a sort function into the C# application which created an index file on the server which everyone else could then use, this worked well but it was slow to create (between 15 - 40 seconds depending on whether you were on wireless or lan).
The solution I decided was to add a script on the server that was capable of recreating the index that my C# application could use. The script is very straight forward and achieves the same indexing task as the C# application did in less than a second.
I started out trying to use scandir but I wasn't having much look and I knew I would maybe want to customise the way this worked later so I implemented my own function for reading in all the directories.
//code for readDirContents function readDirContents( $dir ) { if( !file_exists( $dir ) ) { throw new Exception ( "Directory does not exist" ); } $dir_handle = opendir( $dir ); $dirs = array(); while( false !== ( $file = readdir( $dir_handle ) ) ) { array_push( $dirs, $file ); } closedir( $dir_handle ); return $dirs; }
The code should be fairly self explanatory, we simply ensure the directory exists before creating a handle to the directory and then looping through each of the files in the directory and returning the array.
Looping through each directory would allow me to look at the modified time of the directories but I wanted to use the modified time of the movie file its self. I simply nested another loop calling the function readDirContents function again with the internal directory as a parameter. Once inside my child directory I look for the movie file and store the modified time of the file. I used objects to represent my movies which allowed me to create my own sorting method for comparing dates with my Movie class and then simply calling php's usort did the trick.
Here is the full code, you would obviously have to implement your own endsWith method and writeIndex for your own situation.
$movie_dir = "/mnt/drive2/movies"; $movies = array(); $dirs = readDirContents( $movie_dir ); $counter = 0; if( $dirs !== FALSE ) { $count = 0; foreach( $dirs as $dir ) { if( $dir == "." || $dir == ".." ) continue; if( is_dir( $movie_dir . "/" . $dir ) ) { $movie_file = ""; $movie_name = $dir; $xml_file = ""; $movie_images = array(); $folder_image = ""; $modified_time = ""; //loop through movie files foreach( readDirContents( $movie_dir . "/" . $dir ) as $file ) { $path = $movie_dir . "/" . $dir . "/";//set the full path //echo $file . "\n"; if( endsWith( $file, ".xml" ) ) { //echo "Storing xml file\n"; $xml_file = $file;//save xml file } if( endsWith ( $file, ".avi" ) ) { $movie_file = $file; //get modified time $modified_time = filemtime( $path . "/" . $file ); } if ( $file == "folder.jpg" ) { $folder_image = $file; } if( endsWith( $file, ".jpg" ) && $file != "folder.jpg" ) { array_push( $movie_images, $file );//save the images } }//end loop through files //create the movie object and save it array_push( $movies, new Movie( $movie_name, $movie_file, $xml_file, $folder_image, $movie_images, $modified_time ) ); }//end is a directory //break; $counter++; }//end loop through movie dirs //write index writeIndex( $movies, $counter ); } else { echo "Directory does not exist"; } ?>
Add new comment