Skip to content

Instantly share code, notes, and snippets.

@cballou
Created September 25, 2012 10:57
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save cballou/3781156 to your computer and use it in GitHub Desktop.
Save cballou/3781156 to your computer and use it in GitHub Desktop.
Download a file via FTP with auto-resume functionality in case of any disconnects.
<?php
/**
* Copyright (C) <2012> <Corey Ballou>
* @author Corey Ballou <http://www.craftblue.com>
* @license MIT License
*/
/**
* Handles FTP download of a remote file and stores it in a local file.
*
* @param string $ftpServer The FTP server to connect to, i.e. ftp.server.com
* @param string $username The FTP username
* @param string $password The FTP password
* @param string $remoteFilePath The path to the remote file if necessary
* @param string $localFilePath The full path to the local file
* @param int $port The FTP server port, 21 is standard
* @return bool
*/
function download(
$ftpServer,
$username,
$password,
$remoteFilePath,
$localFilePath,
$port = 21,
$timeout = 30)
{
// set up basic connection
$conn = ftp_connect($ftpServer, $port, $timeout)
or die('Could not connect to FTP server.');
// login with username and password
if (@ftp_login($conn, $username, $password)) {
// turn on PASV mode
@ftp_pasv($conn, TRUE);
// attempt to download the file, with retries
return _download($conn, $remoteFilePath, $localFilePath);
} else {
if (!empty($conn)) {
ftp_close($conn);
}
die('Access credential problem connecting to FTP server.');
}
if (!empty($conn)) {
ftp_close($conn);
}
return false;
}
/**
* Handle file downloads with attempted retries. Note that filesize() doesn't
* work on all machines. Also, depending on the file type, you may need to swap
* out FTP_BINARY for FTP_ASCII.
*
* @param resource $conn
* @param string $remoteFilePath The path to the remote file if necessary
* @param string $localFilePath The full path to the local file
* @param int $retries
*/
function _download($conn, $remoteFilePath, $localFilePath, $retries = 1)
{
// check if the local file already exists to determine resume d/l position
$resumePosition = 0;
if (file_exists($localFilePath)) {
$resumePosition = filesize($localFilePath);
}
// attempt to download with auto-resume capabilities up to 5 retries
if (@ftp_get($conn, $localFilePath, $remoteFilePath, FTP_BINARY, $resumePosition)) {
if (!empty($conn)) {
ftp_close($conn);
}
return true;
} else if ($retries < 5) {
// retry up to five times
return _download($conn, $remoteFilePath, $localFilePath, $retries + 1);
} else {
die('There was a problem downloading the remote file.');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment