Welcome Guest, Not a member yet? Register   Sign In
Headers for file download the CI way
#1

[eluser]mr_prasanna[/eluser]
Hi

I tried the set output header method to do the following but had no luck. Browsers displayed the binary stream instead of forcing to download. What's the most graceful way to achieve this in CI?

This snippet is part of 'download' function in a controller:
Code:
header('Content-Description: File Transfer');
                    header('Content-Type: application/octet-stream');
                    header('Content-Disposition: attachment; filename="'.$f_name.'"');
                    header('Content-Length: ' . filesize($f_full));
                    ob_clean();
                    flush();
                    readfile($f_full);
                    exit;
#2

[eluser]flaky[/eluser]
http://ellislab.com/codeigniter/user-gui...elper.html
#3

[eluser]mr_prasanna[/eluser]
What scared me in this method is, what if the file size is like 50MB, 80+MB or 1GB?
Will it still work fine and efficient than any other alternative PHP has to offer?

Code:
$data = file_get_contents("/path/to/photo.jpg"); // Read the file's contents
$name = 'myphoto.jpg';

force_download($name, $data);
#4

[eluser]flaky[/eluser]
As you can see from the code below (download_helper.php), CodeIgniter uses php to set the headers, it doesn't have it's own set of complicated functions, but basically uses php's functions.
Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter
*
* An open source application development framework for PHP 4.3.2 or newer
*
* @package        CodeIgniter
* @author        ExpressionEngine Dev Team
* @copyright    Copyright (c) 2008 - 2009, EllisLab, Inc.
* @license        http://ellislab.com/codeigniter/user-guide/license.html
* @link        http://codeigniter.com
* @since        Version 1.0
* @filesource
*/

// ------------------------------------------------------------------------

/**
* CodeIgniter Download Helpers
*
* @package        CodeIgniter
* @subpackage    Helpers
* @category    Helpers
* @author        ExpressionEngine Dev Team
* @link        http://ellislab.com/codeigniter/user-guide/helpers/download_helper.html
*/

// ------------------------------------------------------------------------

/**
* Force Download
*
* Generates headers that force a download to happen
*
* @access    public
* @param    string    filename
* @param    mixed    the data to be downloaded
* @return    void
*/    
if ( ! function_exists('force_download'))
{
    function force_download($filename = '', $data = '')
    {
        if ($filename == '' OR $data == '')
        {
            return FALSE;
        }

        // Try to determine if the filename includes a file extension.
        // We need it in order to set the MIME type
        if (FALSE === strpos($filename, '.'))
        {
            return FALSE;
        }
    
        // Grab the file extension
        $x = explode('.', $filename);
        $extension = end($x);

        // Load the mime types
        @include(APPPATH.'config/mimes'.EXT);
    
        // Set a default mime if we can't find it
        if ( ! isset($mimes[$extension]))
        {
            $mime = 'application/octet-stream';
        }
        else
        {
            $mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
        }
    
        // Generate the server headers
        if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
        {
            header('Content-Type: "'.$mime.'"');
            header('Content-Disposition: attachment; filename="'.$filename.'"');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header("Content-Transfer-Encoding: binary");
            header('Pragma: public');
            header("Content-Length: ".strlen($data));
        }
        else
        {
            header('Content-Type: "'.$mime.'"');
            header('Content-Disposition: attachment; filename="'.$filename.'"');
            header("Content-Transfer-Encoding: binary");
            header('Expires: 0');
            header('Pragma: no-cache');
            header("Content-Length: ".strlen($data));
        }
    
        exit($data);
    }
}


/* End of file download_helper.php */
/* Location: ./system/helpers/download_helper.php */
#5

[eluser]mr_prasanna[/eluser]
Ok, what if we change this and leave everything else as is. Don't you think it might be better instead of getting a large file's content into PHP variable?

Code:
function force_download($filename = '', $data = '')

To

Code:
function force_download($filename = '', $file_full_path = '')

and

Code:
exit($data);

To

Code:
readfile($file_full_path);
exit;
#6

[eluser]mr_prasanna[/eluser]
Any feedback?
#7

[eluser]danmontgomery[/eluser]
Accomplishes exactly the same thing... The only difference would be that it limits functionality to files that already exist on the filesystem, so you couldn't dynamically generate a file and have the user download it... If it suits your needs, there's no reason not to do it.
#8

[eluser]mr_prasanna[/eluser]
Awesome! So, I think I should customize the helper to do both what it is doing now and a way to just accept filename and do the job which should be quick and doesn't require to pass a large copy of a variable from object to object.

Thanks.




Theme © iAndrew 2016 - Forum software by © MyBB