jack55
February 10, 2018, 7:25pm
1
Hi, I have been going at this for hours trying to fix this but nothing it working. I’m trying to do a simple domain?id=2 etc and then it checks the user has bought the product and that it exists but when it downloads, it says the size and all but when i go to view it, it says corrupted and that the .zip file is invalid so please can someone tell me what i’m doing wrong.
The way im downloading files is by doing getting the full url and then it downloads it but right now its not working and im not too sure why.
Thanks very much
<?php
require_once('../system/config-user.php');
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
function get_remote_file_size($url, $readable = true){
$parsed = parse_url($url);
$host = $parsed["host"];
$fp = @fsockopen($host, 80, $errno, $errstr, 20);
if(!$fp) return false;
else {
@fputs($fp, "HEAD $url HTTP/1.1\r\n");
@fputs($fp, "HOST: $host\r\n");
@fputs($fp, "Connection: close\r\n\r\n");
$headers = "";
while(!@feof($fp))$headers .= @fgets ($fp, 128);
}
@fclose ($fp);
$return = false;
$arr_headers = explode("\n", $headers);
foreach($arr_headers as $header) {
$s = "Content-Length: ";
if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s)) {
$return = trim(substr($header, strlen($s)));
break;
}
}
return $return;
}
function get_ext($name)
{
$fn = get_basename($name);
return (strpos($fn, '.') ? strtolower(substr(strrchr($fn, '.'), 1)) : '');
}
function get_basename($name)
{
return basename(str_replace('\\', '/', $name));
}
function get_filesize_unit($size)
{
$size = max(0, $size);
static $u = array(' B', 'KB', 'MB', 'GB');
for ($i=0; $size >= 1024 && $i < 4; $i++)
{
$size /= 1024;
}
return number_format($size, 1).' '.$u[$i];
}
///////////////////////////////////////////////////////////////////////////////////////////////
function find_mime_type($ext)
{
static $mime_types = array(
'application/zip' => array('zip')
);
foreach ($mime_types as $mime_type => $exts)
{
if (in_array($ext, $exts))
{
return $mime_type;
}
}
return 'text/plain';
}
$id = $_GET['id'];
$error = false;
$error = (!$product->is_product($id)?$products->error:$error);
$error =(!$purchases->is_purchased($_SESSION['uid'],$id)?$purchases->error:$error);
if(!$error){
$file = $product->details($id);
$filepath = $file['file'];
$fname=get_basename($filepath);
if (fopen($filepath,r) || (file_exists($filepath)) ){
if (@filesize($filepath)){
$fsize =filesize($filepath);
}
else
{
$fsize = get_remote_file_size($filepath);
}
$ext= get_ext($fname);
$ctype= find_mime_type($ext);
header('Content-Type:'. $ctype );
header('Content-Length: ' . $fsize);
header('Content-Disposition: attachment; filename=' . $fname);
$file = fopen($filepath,'r');
fpassthru($file);
}else{
return 'File Doesn\'t Exist'; } // exist fxn....
}
echo $error;
//$downloaded = $purchases->update($_SESSION['uid'],$id,'downloaded','1');
?>
Why are errors suppressed by prefixing functions with @ ?
If downloading to Windows this may apply:
Note:
On systems which differentiate between binary and text files (i.e. Windows) the file must be opened with ‘b’ included in fopen() mode parameter.
When I am back on my desktop I will try the script.
Edit:
I would be tempted to try the download examples in the online manual.
jack55
February 11, 2018, 1:32am
3
or if you know a better alternative way to what i’m doing then please say. Thanks in advance
Did you remove @
Did you try the PHP manual examples?
jack55
February 11, 2018, 2:14am
5
yes i removed the @ and checked the manual but still no luck so do you know any better ways of downloading files?
Thanks
I tried the original script online, removed the @ and numerous other minor changes and it now downloads a zip file with the contents of the index.php file.
Download Demo
Edit:
If the download does not work then please supply a link to the file that you are unabel to download.
Source:
<?php
declare (strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(-1);
if(0):
require_once('../system/config-user.php');
endif;
$forum = 'https://www.sitepoint.com/community/t/force-downloading-file-not-working/288661';
$id = $_GET['id'] ?? 1;
$error = false;
$product = NULL;
$products = NULL;
$purchases = NULL;
$error = ( $product && !$product->is_product($id)?$products->error:$error );
$error = ( $purchases && !$purchases->is_purchased($_SESSION['uid'],$id)?$purchases->error:$error );
if(!$error)
{
# DEBUG - FORCE FILE NAME
$fname = 'DOWNLOAD.zip';
$filepath = 'DOWNLOAD.zip';
if(0):
$file = $product->details($id);
$filepath = $file['file'];
$fname = get_basename($filepath);
endif;
if (fopen($filepath, 'r') || (file_exists($filepath)) )
{
if (filesize($filepath))
{
$fsize =filesize($filepath);
}else{
$fsize = get_remote_file_size($filepath);
}
$file = fopen($filepath, 'r');
if(1):
$bytesLeft = fpassthru($file);
$ext = get_ext($fname);
$ctype = find_mime_type($ext);
if(1):
header('Content-Type:' . $ctype );
header('Content-Length: ' . $fsize);
header('Content-Disposition: attachment; filename=' . $fname);
endif;
endif;
# header('Content-Type: plain/txt' );
# echo date('l, F lS Y - H:i:s');
# echo '<br><br><br>';
#DEBUG
if(1):
# header('Content-Type: html');
echo '<br><br><br>';
echo '<br>gettype($error) ==> ' .gettype($error);
echo '<br>$fname ==> ' .$fname;
echo '<br>$fsize ==> ' .number_format( (float) $fsize );
#echo '<br>$ext ==> ' .$ext;
#echo '<br>$ctype ==> ' .$ctype;
echo '<br>$file ==> ' .$file;
echo '<br>bytesLeft ==> <br>' .$bytesLeft;
echo '<br><br> Finished download <br>' . $file;
$style = 'width:88%; margin:4.2em auto; border:solid 1px #ccc; padding:0.88em;';
echo '<div style="' . $style .'">';
highlight_file(__FILE__);
echo '</div>';
else:
$ext = get_ext($fname);
$ctype = find_mime_type($ext);
if(0):
header('Content-Type:' . $ctype );
header('Content-Length: ' . $fsize);
header('Content-Disposition: attachment; filename=' . $fname);
endif;
endif;
}else{
return 'File Doesn\'t Exist';
} // exist fxn....
}//error
echo '<br><br><br>' .$error .'<br><br><br>';
//$downloaded = $purchases->update($_SESSION['uid'],$id,'downloaded','1');
// ONLY FUNCTIONS BELOW
function get_remote_file_size($url, $readable = true)
{
$parsed = parse_url($url);
$host = $parsed["host"];
$fp = fsockopen($host, 80, $errno, $errstr, 20);
if(!$fp)
{
return false;
}else{
fputs($fp, "HEAD $url HTTP/1.1\r\n");
fputs($fp, "HOST: $host\r\n");
fputs($fp, "Connection: close\r\n\r\n");
$headers = "";
while(!feof($fp))
{
$headers .= fgets ($fp, 128);
}
}//endif
fclose ($fp);
$return = false;
$arr_headers = explode("\n", $headers);
foreach($arr_headers as $header)
{
$s = "Content-Length: ";
if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s))
{
$return = trim(substr($header, strlen($s)));
break;
}
}
return $return;
}//
function get_ext($name)
{
$fn = get_basename($name);
return (strpos($fn, '.') ? strtolower(substr(strrchr($fn, '.'), 1)) : '');
}
function get_basename($name)
{
return basename(str_replace('\\', '/', $name));
}
function get_filesize_unit($size)
{
$size = max(0, $size);
static $u = array(' B', 'KB', 'MB', 'GB');
for ($i=0; $size >= 1024 && $i < 4; $i++)
{
$size /= 1024;
}
return number_format($size, 1).' '.$u[$i];
}
///////////////////////////////////////////////////////////////////////////////////////////////
function find_mime_type($ext)
{
static $mime_types = array(
'application/zip' => array('zip')
);
foreach ($mime_types as $mime_type => $exts)
{
if (in_array($ext, $exts))
{
return $mime_type;
}
}
return 'text/plain';
}//
jack55
February 11, 2018, 11:48am
7
Hi John,
Thanks very much for your help, i implemented your code for the download page and tested it with ?id=2 which the $filepath should get this link http://chewiscripts.x10host.com/newspaper.zip and download the file but i got this error
Warning: fopen(DOWNLOAD.zip): failed to open stream: No such file or directory in download.php on line 32
so im unsure but is it because im using a full link for $file[‘file’]; (http://chewiscripts.x10host.com/newspaper.zip )
Thanks
Could you download the DOWNLOAD.zip file?
Try uploading the above file to the same directory that the script is called and see if the download works.
The script is hardcoded to override the $_GET
parameter. Change the 1 to 0 (true to false) and see if the $_GET
parameter works.
I am unable to change my script because I am not on my computer.
jack55
February 11, 2018, 3:56pm
9
Thanks for your quick reply
so you want me to change this $id = $_GET[‘id’] ?? 1; to $id = $_GET[‘id’] ?? 0;
for some reason i’m being very stupid and mind-boggled so i don’t know if im asking too much but would you be able to configure it so it looks at the $_GET id bit so you know ?id=1 gets the download url for product 1 and ?id=2 gets download url for product 2 etc.
Thanks again very much
jack55
February 11, 2018, 6:49pm
10
also one potential reason maybe why its not working is it bad practice to put ?> at the end of every PHP file that i include/require?
jack55:
bad practice to put ?>
Yes, try Googling for an explanation.
I have revised the following script, tested it thoroughly and the download works OK
Online Demo
Source:
<?php
declare (strict_types=1);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(-1);
# echo '<pre>'; print_r($_GET); echo '</pre>';
# echo '<pre>'; var_dump($showDetails); echo '</pre>';
# die;
if(0):
require_once('../system/config-user.php');
endif;
$forum = 'https://www.sitepoint.com/community/t/force-downloading-file-not-working/288661';
$id = $_GET['id'] ?? 1;
$error = false;
$product = NULL;
$products = NULL;
$purchases = NULL;
$error = ( $product && !$product->is_product($id)?$products->error:$error );
$error = ( $purchases && !$purchases->is_purchased($_SESSION['uid'],$id)?$purchases->error:$error );
$style = 'width:88%; margin:4.2em auto; border:solid 1px #ccc; padding:0.88em;';
if(!$error)
{
# DEBUG - FORCE FILE NAME
# $fname = 'DOWNLOAD.zip';
# $filepath = 'DOWNLOAD.zip';
$fname = 'newspaper.zip';
$filepath = 'newspaper.zip';
$filepath = 'https://www/johns-jokes.com/downloads/sp-i/jack55/'
. $filepath;
$fname = get_basename($filepath);
if(0):
$file = $product->details($id);
$filepath = $file['file'];
$fname = get_basename($filepath);
endif;
if (file_exists($fname) )
{
if (filesize($fname))
{
$fsize =filesize($fname);
}else{
$fsize = get_remote_file_size($fname);
}
#
$ext = get_ext($fname);
$ctype = find_mime_type($ext);
$resource = fopen($fname, 'rb');
#DEBUG
$showDetails = $_GET['showDetails'] ? TRUE : FALSE;
if( $showDetails)
{
# echo '<pre>'; print_r($_GET); echo '</pre>';
# echo '<pre>'; var_dump($showDetails); echo '</pre>';
echo '<b style="float:right;"><a href="' .$forum .'"> Forum </a> </b>';
echo '<hr style="clear:both;">';
echo '<h1> Download: <a href="??showDetails=FALSE"> ' .$fname .' </a> </h1>';
echo '<hr style="clear:both;">';
echo '<br>gettype($error) ==> ';
echo gettype($error) ? 'TRUE' : '';
echo '<br>$fname ==> ' .$fname;
echo '<br>$fsize ==> ' .number_format( (float) $fsize );
echo '<br>$resource ==> ' .$resource;
echo '<br>$ext ==> ' .$ext;
echo '<br>$ctype ==> ' .$ctype;
echo '<div style="' . $style .'">';
highlight_file(__FILE__);
echo '</div>';
}else{
$bytes = fpassthru($resource);
header('Content-Type:' .$ctype );
header('Content-Length: ' .$fsize);
header('Content-Disposition: attachment; filename=' . $fname);
}//endif;
}else{
return '<h1>File Doesn\'t Exist ==> ' .$fname .'</h1>';
} // exist fxn....
}//error
echo '<br><br><br>' .$error .'<br><br><br>';
//$downloaded = $purchases->update($_SESSION['uid'],$id,'downloaded','1');
// ONLY FUNCTIONS BELOW
function get_remote_file_size($url, $readable = true)
{
$parsed = parse_url($url);
$host = $parsed["host"];
$fp = fsockopen($host, 80, $errno, $errstr, 20);
if(!$fp)
{
return false;
}else{
fputs($fp, "HEAD $url HTTP/1.1\r\n");
fputs($fp, "HOST: $host\r\n");
fputs($fp, "Connection: close\r\n\r\n");
$headers = "";
while(!feof($fp))
{
$headers .= fgets ($fp, 128);
}
}//endif
fclose ($fp);
$return = false;
$arr_headers = explode("\n", $headers);
foreach($arr_headers as $header)
{
$s = "Content-Length: ";
if(substr(strtolower ($header), 0, strlen($s)) == strtolower($s))
{
$return = trim(substr($header, strlen($s)));
break;
}
}
return $return;
}//
function get_ext($name)
{
$fn = get_basename($name);
return (strpos($fn, '.') ? strtolower(substr(strrchr($fn, '.'), 1)) : '');
}
function get_basename($name)
{
return basename(str_replace('\\', '/', $name));
}
function get_filesize_unit($size)
{
$size = max(0, $size);
static $u = array(' B', 'KB', 'MB', 'GB');
for ($i=0; $size >= 1024 && $i < 4; $i++)
{
$size /= 1024;
}
return number_format($size, 1).' '.$u[$i];
}
///////////////////////////////////////////////////////////////////////////////////////////////
function find_mime_type($ext)
{
static $mime_types = array(
'application/zip' => array('zip')
);
foreach ($mime_types as $mime_type => $exts)
{
if (in_array($ext, $exts))
{
return $mime_type;
}
}
return 'text/plain';
}//
jack55
February 12, 2018, 11:07pm
13
thanks for your help and i think it may of just been that the newsletter.zip file was corrupt or something but this code below fixed it but thanks very much anyway John
$id = $_GET['id'];
$error = false;
$error = (!$product->is_product($id)?$products->error:$error);
$error =(!$purchases->is_purchased($_SESSION['uid'],$id)?$purchases->error:$error);
if(!$error) {
$file = $product->details($id);
$file_url = $file['file'];
//Works
ob_clean();
ob_end_flush();
header('Content-type: application/zip');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
readfile($file_url);
unlink($file_url);
}
echo $error;
1 Like
system
Closed
May 15, 2018, 6:07am
14
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.