Skip to content
Advertisement

FTP download folder with php

So I was wondering for I can download a intire folder from my FTP server, just by clicking on a link. When I have to download my .log files from my FTP server I do this:

First I create a link:

function FTP_download($id, $folder = ""){
    ?> <a href="ftp_download.php?folder=<?php echo $folder; ?>&id=<?php echo $id;?>&file=<?php echo $id.'.log'; ?>" download> Download full log </a> <?php
}

Then I call the downloader file:

<?php
//Does GET exist
if (!isset($_GET['file'])) {
    echo"ERROR - loading log";
    return false;
}

//Define FTP variables
$ftp_server = "xxxx";
$ftp_user_name = "xxxx";
$ftp_user_pass = "xxxx";
$file = $_GET['file'];
$id = $_GET['id'];
$folder = $_GET['folder'];
// set up basic connection
$conn_id = ftp_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);


// Change dir to id folder
ftp_chdir($conn_id, $id);
// Change dir to logs
ftp_chdir($conn_id, $folder);

//Check if file exists
ftp_pasv($conn_id, true);
$list = ftp_nlist($conn_id, '');
if (!in_array($file, $list)) {
    return false;
}


// get the size of $file
$size = ftp_size($conn_id, $file);

//Create headers for force download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $size);

//Read file content
readfile('ftp://'.$ftp_user_name.':'.urlencode($ftp_user_pass).'@'.$ftp_server.'/'.$id.'/'.$folder.'/'.$file);
ftp_close($conn_id);
return true;
?>

By clicking the link, a browser download is started.

enter image description here

Is it possible to create a download file which downloads the whole folder, with all content in it?

Like download -> 'ftp://'.$ftp_user_name.':'.urlencode($ftp_user_pass).'@'.$ftp_server.'/'.$id.'/'.$folder

Advertisement

Answer

What i would do, is downloading all the files in the /tmp directory and then zip them all together into an archive. This file can then be streamed for as a response.

Make sure though that your tmp directory gets cleared, which normaly php does on its own after the request finished see here.

PHP ZipArchive

If you want to download all files within a single request (not within a folder).
This could work when using the ‘Content-Disposition’ value as a seperator between the file contents. I cannot confidently explain you what you would need for that. Maybe googling for ‘mulipart form request’ will give you a tutorial on that.

As for creating a direct folder as a response, i have never seen such a feature and don’t think it is possible.

In my opinion Zip is the best option here, as it should be supported widely enough, and keeps your folders intact, wich i think you want to keep.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement