PHP Script To Monitor FTP Directory Changes

|

I recently had the need to be able to monitor a directory on an FTP server for changes and to then be notified of those changes. I’ve been working a lot in PHP lately so I decided to use that to implement my script.

FTP Access

FTP (file transfer protocol) access in PHP is a breeze. It’s as simple as this:

// Connect to FTP host
$conn = ftp_connect($host, $port) or die("Could not connect to {$host}\n");

// Login
if(ftp_login($conn, $user, $pass)) {
  // Retrieve directory listing
  $files = ftp_nlist($conn, $remote_dir);
}

// Close Connect
ftp_close($conn);

Easy, right? Of course I left out a few pieces of the puzzle, but I just wanted to show how easy it is to actually get to an FTP server, login and get a directory listing.

Comparisons

After retrieving the listing which is an array I remove out the “.” and “..” listings as they are special system directories meaning “the current directory” and “the parent directory” respectively.

$ftpFiles = array();
foreach($files as $file)
{
  // Get just the filename without directory information
  $thisFile = basename($file);
  if($thisFile != '.' && $thisFile != '..')
  {
    // Append to our new array
    $ftpFiles[] = $thisFile;
  }
}

Now the header for this section is Comparisons, so what exactly are we comparing to? Each time this script runs we store a serialized version of this array out to file. I read the file into an array and compare it with the one we just created from the FTP directory.

$currentFiles = array();
if(file_exists($cache_file))
{
  // Read contents of file
  $handle = fopen($cache_file, "r");
  if($handle)
  {
    $contents = fread($handle, filesize($cache_file));
    fclose($handle);

    // Unserialize our array from the file contents
    $currentFiles = unserialize($contents);
  }
}

Now that we have an array of files (and directories) that we just pulled from the FTP server and an array that we saved from the last time we ran we can just compare the two.

$diff = array_diff($ftpFiles, $currentFiles);
if(count($diff) > 0)
{
  // There are changes so do some stuff here.
  // In the download script I actually compile and send an email with the files listed
}

Finally, I write the contents of the new array back out to the cache file so we can use it to compare on the next run.

// Write new file list out to cache
$handle = fopen($cache_file, "w");
fwrite($handle, serialize($ftpFiles));
fflush($handle);
fclose($handle);

Summary and Download

So that’s it! Pretty simple. On my server I pre-pended the following to the file:
#!/usr/bin/env php
and changed the file mode so that it could be executed. I then setup a cron job to run at 8 o’clock every morning like this:

> crontab -e

# This is added to crontab
0 8 * * * ~/ftpMonitor.php

Here is the complete file in a zip file. Open the file in any text editor and you will see a configuration section at the top where you can set your FTP host information and email information.

ftpMonitor.zip

I hope you have enjoyed this short tutorial and may possibly find it useful. If you have any comments or suggestions for improvement please feel free to leave those in the comments section below. Thanks for stopping by!