用PHP下载数字产品的最佳方法是什么?

时间:2021-08-19 18:10:21

Digital commercial products that customers pay for download link.

客户为下载链接付费的数字商业产品。

I have put all the zipped files (products) outside of web document root and buyers download them via a php script which is integrated with paypal IPN to make sure the downloader is a paying buyer.

我已将所有压缩文件(产品)放在web文档根目录之外,买家通过与paypal IPN集成的php脚本下载它们,以确保下载者是付费买家。

Sort of like: http://www.mysite.com/download.php?buyer_id=xxx

类似于:http://www.mysite.com/download.php?buyer_id = xxxx

Thus far it all works with only one problem. The zip files I download via the URL above is corrupted and can't be opened correctly with WinRAR. However, directly downloaded zip is fine.

到目前为止,一切只能解决一个问题。我通过上面的URL下载的zip文件已损坏,无法使用WinRAR正确打开。但是,直接下载的zip很好。

My code:

$path = WAREHOUSE_PATH.'/products/'.$identifier.'.zip';
$mm_type="application/octet-stream";
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");

$fp = @fopen($path,"rb");
if ($fp) {
  while(!feof($fp)) {
    print(fread($fp, 1024*8));
    flush();
    if (connection_status()!=0) {
      @fclose($fp);
      die();
    }
  }
  @fclose($fp);
}

What could be wrong? Thanks!

可能有什么不对?谢谢!

Problem solved: Thank you all for the tips. It turns out that the downloaded packages contains a few extra white spaces which shouldn't be there. Silly.

问题解决了:谢谢大家的提示。事实证明,下载的软件包包含一些不应该存在的额外空白区域。愚蠢。

3 个解决方案

#1


You'd be better off just using readfile(). Unless you have ignore_user_abort on, then the script will terminate automatically if the user cancels anyway.

你最好只使用readfile()。除非你有ignore_user_abort,否则如果用户取消,脚本将自动终止。

If you're still having problems, load the file up in a hex editor and compare the first few characters and the last few characters.

如果您仍然遇到问题,请在十六进制编辑器中加载文件,并比较前几个字符和最后几个字符。

#2


I would suggest changing this:

我建议改变这个:

$fp = @fopen($path,"rb");
if ($fp) {
  while(!feof($fp)) {
    print(fread($fp, 1024*8));
    flush();
    if (connection_status()!=0) {
      @fclose($fp);
      die();
    }
  }
  @fclose($fp);
}

to this

readfile($path);

You can find more info on readfile here, but basically it will do everything your loop does.

你可以在这里找到有关readfile的更多信息,但基本上它会完成你的循环所做的一切。

#3


You have an extra newline character for your Content-Transfer-Encoding header - perhaps that is resulting in three newline characters between the last header and the body?

您的Content-Transfer-Encoding标头有一个额外的换行符 - 也许这会在最后一个标题和正文之间产生三个换行符?

#1


You'd be better off just using readfile(). Unless you have ignore_user_abort on, then the script will terminate automatically if the user cancels anyway.

你最好只使用readfile()。除非你有ignore_user_abort,否则如果用户取消,脚本将自动终止。

If you're still having problems, load the file up in a hex editor and compare the first few characters and the last few characters.

如果您仍然遇到问题,请在十六进制编辑器中加载文件,并比较前几个字符和最后几个字符。

#2


I would suggest changing this:

我建议改变这个:

$fp = @fopen($path,"rb");
if ($fp) {
  while(!feof($fp)) {
    print(fread($fp, 1024*8));
    flush();
    if (connection_status()!=0) {
      @fclose($fp);
      die();
    }
  }
  @fclose($fp);
}

to this

readfile($path);

You can find more info on readfile here, but basically it will do everything your loop does.

你可以在这里找到有关readfile的更多信息,但基本上它会完成你的循环所做的一切。

#3


You have an extra newline character for your Content-Transfer-Encoding header - perhaps that is resulting in three newline characters between the last header and the body?

您的Content-Transfer-Encoding标头有一个额外的换行符 - 也许这会在最后一个标题和正文之间产生三个换行符?