PHP Force Download Causing 0 Byte Files

后端 未结 8 1109
清歌不尽
清歌不尽 2020-12-10 16:11

I\'m trying to force download files from my web server using PHP. I\'m not a pro in PHP but I just can\'t seem to get around the problem of files downloading in 0 bytes in s

相关标签:
8条回答
  • 2020-12-10 16:51

    You're not checking that the file exists. Try using this:

    $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;
    }else
    {
        echo "File does not exists";
    }
    

    And see what you get.


    You should also note that this forces a download as an octet stream, a plain binary file. Some browsers will struggle to understand the exact type of the file. If, for example, you send a GIF with a header of Content-Type: application/octet-stream, then the browser may not treat it like a GIF image. You should add in specific checks to determine what the content type of the file is, and send an appropriate Content-Type header.

    0 讨论(0)
  • 2020-12-10 16:53

    if script work work for small files but for huge files return 0 byte file. you must increate memory_limit via php.ini also you can add the following line before your code

    ini_set('memory_limit','-1');
    
    0 讨论(0)
  • 2020-12-10 16:54

    i am doing this to download a PDF ...

    $filename = 'Application.pdf';
    header("Content-Type: application/pdf");
    header("Content-Disposition: attachment; filename=$filename");
    echo $pdf;
    

    i think you are missing the last row, where you actually send the file contents of whatever you have in $file.

    Pablo

    0 讨论(0)
  • 2020-12-10 17:01

    This problem as same as my website project. This code I've used:

    <?php
    
    $file = $_SERVER["DOCUMENT_ROOT"].'/.../.../'.$_GET['file'];
    
     if(!file)
     {
         // File doesn't exist, output error
         die('file not found');
     }
     else
     {
    
        //$file_extension = strtolower(substr(strrchr($file,"."),1));
        $file_extension = end(explode(".", $file));
    
        switch( $fileExtension)
        {
        case "pdf": $ctype="application/pdf"; break;
        case "exe": $ctype="application/octet-stream"; break;
        case "zip": $ctype="application/zip"; break;
        case "doc": $ctype="application/msword"; break;
        case "xls": $ctype="application/vnd.ms-excel"; break;
        case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
        case "gif": $ctype="image/gif"; break;
        case "png": $ctype="image/png"; break;
        case "jpeg":
        case "jpg": $ctype="image/jpg"; break;
        default: $ctype="application/force-download";
        }
    
        nocache_headers();
    
         // Set headers
        header("Pragma: public"); // required
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: public"); // required for certain browsers
        header("Content-Description: File Transfer");
        header("Content-Type: $ctype");
        header("Content-Disposition: attachment; filename=".$file.";" );
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($file));
    
         readfile($file);
     }
     ?>
    

    I think the problem is on the server setting like PHP setting or cache setting, but I don't have any idea to do this my opinion.

    0 讨论(0)
  • 2020-12-10 17:02

    I use the following method in phunction and I haven't had any issues with it so far:

    function Download($path, $speed = null)
    {
        if (is_file($path) === true)
        {
            $file = @fopen($path, 'rb');
            $speed = (isset($speed) === true) ? round($speed * 1024) : 524288;
    
            if (is_resource($file) === true)
            {
                set_time_limit(0);
                ignore_user_abort(false);
    
                while (ob_get_level() > 0)
                {
                    ob_end_clean();
                }
    
                header('Expires: 0');
                header('Pragma: public');
                header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                header('Content-Type: application/octet-stream');
                header('Content-Length: ' . sprintf('%u', filesize($path)));
                header('Content-Disposition: attachment; filename="' . basename($path) . '"');
                header('Content-Transfer-Encoding: binary');
    
                while (feof($file) !== true)
                {
                    echo fread($file, $speed);
    
                    while (ob_get_level() > 0)
                    {
                        ob_end_flush();
                    }
    
                    flush();
                    sleep(1);
                }
    
                fclose($file);
            }
    
            exit();
        }
    
        return false;
    }
    

    You can try it simply by doing:

    Download('/path/to/file.ext');
    
    0 讨论(0)
  • 2020-12-10 17:02

    The trick is to check with file_exists to confirm the correct path. The big confusion is that for PHP paths you don't need to start with '/' to say your website start path.

     '/folder/file.ext'  #bad, needs to know the real full path
    

    in php / is the website main path already, you don't need to mention it. Just:

     'folder/file.ext'   #relative to the / website
    

    This will work with file_exists, header filename, readfile, etc...

    0 讨论(0)
提交回复
热议问题