Jump to content

Download file through PHP connection to external FTP Server


vanlier

Recommended Posts

I have a client with a hosted webserver and a local FTP server. When a customer logs in he should be able to browse files on the FTP and download the files. The files are highres pics with sizes from 1 - 200 MB.

 

I already used PHP's built-in ftp functions to browse the ftp-server and that is working ok. But when I want to download the files the only option I got working so far is to download the file from the ftpserver to the webserver and then push it to the browser. The problem is I don't want to download it to a file on the webserver first but directy 'stream it to the client as a download'.

 

The ftp-server is password protected. I tried fopen("username:password@server/path/file") and then use fpassthru() on the handle but fopen does not work. When I try with ftp_get I have to download it to a file (i think?). I also tried using cUrl but didn't get that working either?

 

This was the code I tried:

 

<?php
// show all errors
error_reporting(E_ALL);
ini_set('display_errors', '1');

// start session
session_start();

// set ftp data
$server='<server>';
$port = 21;
$username='<username>';
$password='<password>';

// Prevent files from showing
$prevent_download = array();
array_push($prevent_download,'Thumbs.db');
array_push($prevent_download,'.htaccess');
array_push($prevent_download,'.htpasswd');

// Set up connection
$conn = ftp_connect($server,$port);
$login = ftp_login($conn, $username, $password);

// Get current working dir
if (!isset($_SESSION['wdir'])) { $_SESSION['wdir'] = '/'; }

// Set new dir if needed
if (isset($_GET['cd']))
  {
  $_GET['cd'] = str_replace('//','/',$_GET['cd']);
  $_SESSION['wdir'] = $_GET['cd'];
  }

// Change to dir
$chdir = @ftp_chdir($conn,$_SESSION['wdir']);

// Check if downloading:
if (isset($_GET['download']))
  {
  // ============= HERE IS THE FTP 'STREAM' PART ===========================
  
  // set needed info
$url  = "ftp://$username:$password@$server".$_GET['download'];	
  $file = basename($_GET['download']);
  
header("Content-disposition: attachment; filename=\"$file\"");
header("Content-type: application/octet-stream");
header("Pragma: ");
header("Cache-Control: cache");
header("Expires: 0");

  
  error_reporting(E_ALL);
  ini_set('display_errors', '1');

  $fh = fopen('download/file.txt', 'w') or die($php_errormsg); 
  
  echo "$url";
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_FILE, $fh);
  curl_exec ($ch);
  curl_close ($ch);
  
  // end script, download finished
  exit;

  // ============= END OF THE FTP 'STREAM' PART ===========================
  }

// set root dir
$cdir = "<a href='ftp.php?cd=/'>Root</a>";
$cddir = "/";

// set up split path links
if ($_SESSION['wdir']!='/')
  {
  $dirparts = explode("/",substr($_SESSION['wdir'],1));

  foreach ($dirparts as $part)
    {
    $cddir .= "/".$part;
    $cdir .= " / <a href='ftp.php?cd=$cddir'>$part</a>";
    }
  }

// prevent double slash
if ($_SESSION['wdir']=='/')
  {
  $_SESSION['wdir']='';
  }
  
// show path links
echo "Location: $cdir<p>";

// get listing from current dir
$filelist = ftp_rawlist($conn, "-al .");

foreach ($filelist as $filename)
  {  
  if (substr($filename,24,5)=='<DIR>')
    {
    $filename=substr($filename,39);

    // Dir so add CD link
    echo "[DIR] <a href='ftp.php?cd=".$_SESSION['wdir']."/".htmlspecialchars($filename)."'>".htmlspecialchars($filename)."</a><br>";
    }
  else
    {
    $filename=substr($filename,39);

    // Check if not prevented from download
    if (!in_array(basename($filename),$prevent_download))
      {
      // File so add Download link
      echo "<a href='ftp.php?download=".$_SESSION['wdir']."/".htmlspecialchars($filename)."'>".htmlspecialchars($filename)."</a><br>";
      }
    }
  }
?>

 

 

anyone??

Hi Thorpe, thanx for the reply.

 

I understand the webserver needs to 'pass' the bits. I just don't want to save to file but output to browser so the client can download the data downloaded from ftp.

 

Could you please post an example how to directly output data from ftp_nb_fget to the browser? (so not download 50mb and then output 50mb to browser but in blocks of 1024 bytes or something so the clients doesn't have to wait for the webserver to download the whole file)

 

P.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.