javascriptphphtmlx-sendfile

PHP, X-SendFile: Sending file together with outputting text to the browser (via echo)


I use X-SendFile Apache Module to download large files from the server. Downloads work well. However, when the download starts, I need to output some text to the browser, such as: "Thanks for downloading the file...."

My problem is, that I can not do both in one script. I can either download the file, and then no text is output to the screen. Or, I can output the text to the screen, but then the download script won't start.

How to do both tasks in one PHP script please - downloading a file and sending text content to the browser/webpage? The problem probably originates in HTTP output headers, but I do not know how to solve it.

This it the sample code I use to download files via X-SendFile (works properly on its own):

header('Content-Description: File Transfer');
header("Content-Disposition: attachment; filename=\"". basename($filePath) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Content-Length: ' . filesize($filePath));
header("X-Sendfile: $filePath");

For completion, this is my test echo"" string. If it is placed above the X-Sendfile code, it gets output, but download will not start. If it is put below the X-Sendfile code, the file gets downloaded, but nothign is echoed to the browser:

echo "SUCCESS!!!";
ob_flush();

Constraint:

I need to be able to download the file easily via URL. Example, www.mydomain.com/?fileID=asl523n53twteHLfga. In other words, the PHP download script is within index.php. When the user enters www.mydomain.com, the domain landing page gets displayed. However, when the additional $_GET variable is passed, PHP script recognizes that, and should display Thank you for downloading... instead of the landing page.

A workaround is welcome. Important is to achived the desired result while keeping the above constraint. Tahnk you very much.


Solution

  • How about adding a separate download page that will download the file (i.e. download.php?fileID=XYZ) and having your index page show a message like so:

    <?php
    
    function homeScreen() {
      // your home content
    }
    
    function downloadFileScreen ($id) {
    ?>
    <h2>Thank you for your download!</h2>
    Your download should start automatically, if it does not, click 
    <a href="download.php?fileID=<?php print $id; ?>">here</a>
    <script type="text/javascript">
    window.setTimeout('location.href="download.php?fileID=<?php print $id; ?>"',3000);
    </script>
    <?php
    }
    
    if (isset($_GET['fileID'])) {
      $id= $_GET['fileID'];
      downloadFileScreen ($id);
    ?>
    } else {
      // no ID passed, show home screen
      homeScreen();
    }
    ?>
    

    I haven't heard of any browser support mixing both download and HTTP content display in a single request, but I'll have a look if this can be achieved using ob_start() and ob_flush().