Jump to content

PHP Large File Download Problem


jjlarkin

Recommended Posts

I’m having a problem with want I believe to be the php (version 4.4.4) setting on my host site.  My problem is I’m not a php programmer (although I am a programmer) so I don’t really understand what is going on to debug it. 

 

The problem with the site is when I try and download large files using php headers the file downloads to my computer but it is not the correct size.  This only happens with large files.  An example would be I download a 130 MBs file it says that it downloaded but when I look at the size of the file it is only 35MBs.

 

I using Joomla for my site and I have tried various different download packages for the site but all of them seem to use this php header method to download files.  If I FTP to the site to download I have no problems.  I have been able to break the problem down to one simple php script.  Note I did not write this code it just the code I have cleaned up from a Joomla add-on.  I believe the script works fine because the file will start downloading but something in either the php or apache setting are causing it to stop short

 

 

PHP Code

<?php

 

function readFileChunked($filename,$retbytes=true) {

$chunksize = 1*(1024*1024); // how many bytes per chunk

$buffer = '';

$cnt =0;

// $handle = fopen($filename, 'rb');

$handle = fopen($filename, 'rb');

if ($handle === false) {

return false;

}

while (!feof($handle)) {

$buffer = fread($handle, $chunksize);

echo $buffer;

sleep(1);

ob_flush();

flush();

if ($retbytes) {

$cnt += strlen($buffer);

}

}

$status = fclose($handle);

if ($retbytes && $status) {

return $cnt; // return num. bytes delivered like readfile() does.

}

return $status;

}

 

 

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

function download_item($dir, $item, $unlink=false) { // download file

global $action, $mosConfig_cache_path;

// Security Fix:

$item=basename($item);

 

while( @ob_end_clean() );

ob_start();

 

if( true) {

$abs_item = $dir.'/'.$item;

}

 

 

// Note this may have to change base on brower type

$browser='OPERA';

 

header('Content-Type: '.(($browser=='IE' || $browser=='OPERA')?

'application/octetstream':'application/octet-stream'));

header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');

header('Content-Transfer-Encoding: binary');

header('Content-Length: '.filesize(realpath($abs_item)));

//header("Content-Encoding: none");

if($browser=='IE') {

header('Content-Disposition: attachment; filename="'.$item.'"');

header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

header('Pragma: public');

} else {

header('Content-Disposition: attachment; filename="'.$item.'"');

header('Cache-Control: no-cache, must-revalidate');

header('Pragma: no-cache');

}

@set_time_limit( 0 );

@readFileChunked($abs_item);

 

if( $unlink==true ) {

unlink( $abs_item );

}

ob_end_flush();

exit;

}

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

 

download_item(LocalPath,testfile)

 

 

?>

 

My Php.ini file

 

; This is the default PHP 4-style version of the php.ini settings file.

; It is based on /usr/local/etc/php.ini-recommended. For full reference

; of all possible configuration directives and their default values,

; please visit http://www.php.net/manual/en/print/ini.php

 

allow_call_time_pass_reference = Off ; Code cleanliness

magic_quotes_gpc = Off ; Performance

output_buffering = 10000 ; Performance

register_argc_argv = Off ; Performance

;register_globals = Off                ; Security, Performance [default]

variables_order = "GPCS" ; Performance

zlib.output_compression = On ; Performance

 

cgi.fix_pathinfo = 1

error_reporting = E_ALL & ~E_NOTICE

fastcgi.log = 0

max_execution_time = 0

max_input_time = 0

memory_limit = 200M

safe_mode_exec_dir =

upload_max_filesize = 500M

post_max_size = 600M

url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry"

allow_url_fopen = On

 

[session]

session.bug_compat_42 = 0

session.gc_divisor = 1000

 

[eaccelerator]

extension="eaccelerator.so" ; [Performance]

eaccelerator.cache_dir="/tmp"

eaccelerator.shm_size="4"

eaccelerator.shm_only="1"

 

; The following PHP4 extensions are pre-loaded by default (i.e. built static)

; - ctype

; - mysql

; - openssl

; - overload

; - pcre

; - posix

; - session

; - tokenizer

; - xml

; - zlib

 

; The following ones are dynamic and could be loaded on demand.

; In order to pre-load some of the following extensions,

; you would need to uncomment the appropriate line(s) below.

 

;extension=curl.so

;extension=domxml.so

;extension=ftp.so

;extension=gd.so

;extension=gettext.so

;extension=imap.so

;extension=mbstring.so

;extension=mcrypt.so

;extension=mhash.so

;extension=sockets.so

;extension=sqlite.so

;extension=templates.so

;extension=xslt.so

 

Any help you can give would be great thanks.

 

-James

Link to comment
Share on other sites

If I had to guess, and I am guessing, you may be exceeding the time limit for execution of a php script.  The "readFileChunked" function has a sleep for 1 second in it after every 1 MB of data it outputs.  Usually the default max execution time of a php script is around 30 seconds...

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.