Asked  7 Months ago    Answers:  5   Viewed   42 times

What code do you need to add in PHP to automatically have the browser download a file to the local machine when a link is visited?

I am specifically thinking of functionality similar to that of download sites that prompt the user to save a file to disk once you click on the name of the software?

 Answers

25

Send the following headers before outputting the file:

header("Content-Disposition: attachment; filename="" . basename($File) . """);
header("Content-Type: application/octet-stream");
header("Content-Length: " . filesize($File));
header("Connection: close");

@grom: Interesting about the 'application/octet-stream' MIME type. I wasn't aware of that, have always just used 'application/force-download' :)

Wednesday, March 31, 2021
 
Marcelo
answered 7 Months ago
50

Here is a simple function that can compress any file or directory recursively, only needs the zip extension to be loaded.

function Zip($source, $destination)
{
    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\', '/', realpath($source));

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {
            $file = str_replace('\', '/', $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

Call it like this:

Zip('/folder/to/compress/', './compressed.zip');
Wednesday, March 31, 2021
 
innovation
answered 7 Months ago
85
<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}

?>

As you can see Content type is application/octet-steam meaning file is byte by byte encoded. Also the cache headers are set. Then headers are forcefully sent by ob_clean();flush(); and then the file is read.

The file_exists is there to ensure that given file exists. You should also try not not thrust user input as they could easy write names for your php codes and download EACH file. And with ../ in names of the files, even your documents or system files and so on.

Saturday, May 29, 2021
 
Extrakun
answered 5 Months ago
13

The first thing you should do is get a tool like Fiddler and visit a YouTube video page. In Fiddler, you will see all of the files that make up that page, including the FLV itself. Now, you know that the video isn't one of the CSS files, nor is it the image files. You can ignore those. Look for a big file. If you look at the URL, it begins with /videoplayback.

Now, once you've found it, figure out how the browser knew to get that file. Do a search through the sessions (Ctrl+F) and look for "videoplayback". You will see a hit on the first page you went to, like http://www.youtube.com/watch?v=123asdf. If you dig through that file, you'll see a DIV tag with the ID of "watch-player". Within that there is a script tag to setup the flash player, and within that are all of the flash parameters. Within those is the URL to the video.

So now you know how to use your tools to figure out how the browser got to it. How do you duplicate this behavior in PHP?

Do a file_get_contents() on the page that references the video. Ignore everything not in that watch-player div. Parse through the code until you find that variable that contains the URL. From there you will probably have to unescape that URL. Once you have it, you can do a file_get_contents() (or some other download method, depending on what you are trying to do) to get the URL. it is that simple. Your HTML parsing code will be the most complex.

Finally, keep in mind what you are about to do may be illegal. Check the EULA.

Sunday, August 8, 2021
 
im1dermike
answered 3 Months ago
57

Those CMS are probably just calling the JavaScript method window.print to pop up the print dialog:

<span onclick="window.print()" class="pseudo-link">print this document</span>

The rest is then handled by the browser and operating system.

Wednesday, August 18, 2021
 
aphoria
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :