Mohammad
Mohammad

Reputation: 800

php download script error

I use this function to make download link:

    <?php    
function downloadFile($fileLocation,$fileName,$maxSpeed = 13,$doStream =
false){
    if (connection_status()!=0) return(false);
    $extension = strtolower(end(explode('.',$fileName)));

    /* List of File Types */
    $fileTypes['swf'] = 'application/x-shockwave-flash';
    $fileTypes['pdf'] = 'application/pdf';
    $fileTypes['exe'] = 'application/octet-stream';
    $fileTypes['zip'] = 'application/zip';
    $fileTypes['doc'] = 'application/msword';
    $fileTypes['xls'] = 'application/vnd.ms-excel';
    $fileTypes['ppt'] = 'application/vnd.ms-powerpoint';
    $fileTypes['gif'] = 'image/gif';
    $fileTypes['png'] = 'image/png';
    $fileTypes['jpeg'] = 'image/jpg';
    $fileTypes['jpg'] = 'image/jpg';
    $fileTypes['rar'] = 'application/rar';    

    $fileTypes['ra'] = 'audio/x-pn-realaudio';
    $fileTypes['ram'] = 'audio/x-pn-realaudio';
    $fileTypes['ogg'] = 'audio/x-pn-realaudio';

    $fileTypes['wav'] = 'video/x-msvideo';
    $fileTypes['wmv'] = 'video/x-msvideo';
    $fileTypes['avi'] = 'video/x-msvideo';
    $fileTypes['asf'] = 'video/x-msvideo';
    $fileTypes['divx'] = 'video/x-msvideo';

    $fileTypes['mp3'] = 'audio/mpeg';
    $fileTypes['mp4'] = 'audio/mpeg';
    $fileTypes['mpeg'] = 'video/mpeg';
    $fileTypes['mpg'] = 'video/mpeg';
    $fileTypes['mpe'] = 'video/mpeg';
    $fileTypes['mov'] = 'video/quicktime';
    $fileTypes['swf'] = 'video/quicktime';
    $fileTypes['3gp'] = 'video/quicktime';
    $fileTypes['m4a'] = 'video/quicktime';
    $fileTypes['aac'] = 'video/quicktime';
    $fileTypes['m3u'] = 'video/quicktime';

    $contentType = $fileTypes[$extension];


    header("Cache-Control: public");
    header("Content-Transfer-Encoding: binary\n");
    header("Content-Type: $contentType");

    $contentDisposition = 'attachment';

    if($doStream == true){
        /* extensions to stream */
        $array_listen = array('mp3','m3u','m4a','mid','ogg','ra','ram','wm',
        'wav','wma','aac','3gp','avi','mov','mp4','mpeg','mpg','swf','wmv','divx','asf');
        if(in_array($extension,$array_listen)){ 
            $contentDisposition = 'inline';
        }
    }

    if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
        $fileName= preg_replace('/\./', '%2e', $fileName,
substr_count($fileName, '.') - 1);
        header("Content-Disposition: $contentDisposition; filename=".$fileName);
    } else {
        header("Content-Disposition: $contentDisposition; filename=".$fileName);
    }

    header("Accept-Ranges: bytes");   
    $range = 0;
    $size = filesize($fileLocation);

    if(isset($_SERVER['HTTP_RANGE'])) {
        list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
        str_replace($range, "-", $range);
        $size2=$size-1;
        $new_length=$size-$range;
        header("HTTP/1.1 206 Partial Content");
        header("Content-Length: $new_length");
        header("Content-Range: bytes $range$size2/$size");
    } else {
        $size2=$size-1;
        header("Content-Range: bytes 0-$size2/$size");
        header("Content-Length: ".$size);
    }

    if ($size == 0 ) { die('Zero byte file! Aborting download');}
    set_magic_quotes_runtime(0); 
    $fp=fopen("$fileLocation","rb");

    fseek($fp,$range);

    while(!feof($fp) and (connection_status()==0))
    {
        set_time_limit(0);
        print(fread($fp,1024*$maxSpeed));
        flush();
        ob_flush();
        sleep(1);
    }
    fclose($fp);

    return((connection_status()==0) and !connection_aborted());
} 

/* Implementation */
$filename="shopfile.zip";
$location="file/";
downloadFile($location,$filename,900,false); 

?>

but when run it get this eror: Strict Standards: Only variables should be passed by reference in /home/behzadfar/public_html/shopfile/download.php on line 16

Warning: Cannot modify header information - headers already sent by (output started at /home/behzadfar/public_html/shopfile/download.php:16) in /home/behzadfar/public_html/shopfile/download.php on line 57

How can I fix it ?

Upvotes: 1

Views: 116

Answers (3)

Robert Rossmann
Robert Rossmann

Reputation: 12149

To fix the problem: You must pass an actual variable to end(), not a function returning an array. So:

$pieces = explode('.',$fileName);
$extension = strtolower(end($pieces));

This is explained in PHP's manual for end.

Excerpt

This array is passed by reference because it is modified by the function. This means you must pass it a real variable and not a function returning an array because only actual variables may be passed by reference.

Solution without intermediate variable

If you do not want to use an intermediate variable, use array_pop instead of end:

$extension = strtolower(array_pop(explode('.',$fileName)));

The errors related to headers being already sent appear because PHP already had to show you the error on the page (delivered content), thus it blocked itself from the ability to modify the headers (you cannot modify HTTP headers once you start delivering content). Fixing the strict standards error will fix the header errors.

Upvotes: 1

Alex
Alex

Reputation: 17289

why don't you replace that array by http://php.net/manual/en/function.finfo-file.php :

$finfo = new finfo(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension

$contentType =  $finfo->file($fileLocation.$filename) ;

does your script starts with 4 or any spaces??

Upvotes: 0

Lorenz Meyer
Lorenz Meyer

Reputation: 19945

The error comes from this line:

$extension = strtolower(end(explode('.',$fileName)));

end()'s parameter is passed by reference (see manual: mixed end ( array &$array )

You must therefore change your code to:

$array = explode('.',$fileName);
$extension = strtolower(end($array));

Look also into pathinfo(), this would be a cleaner solution:

$extension = pathinfo($fileName, PATHINFO_EXTENSION);

Why implement yourself this function if it is already part of standard php functions.

Upvotes: 0

Related Questions