我想提供发票供下载。目前我使用的是简单的编号方案(invoice-01.pdf、invoice-02.pdf 等)。我知道我可以使用哈希来隐藏数据。
是否也可以使用 PHP 并通过不让用户直接指向发票来提供发票?
答案1
甚至还有这样的例子php.net
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// The PDF source is in original.pdf
readfile('original.pdf');
?>
或者稍微扩展一下
<?php
if ( can_this_file_be_downloaded() ) {
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="invoice.pdf"');
readfile("{$_GET['filename']}.pdf");
} else {
die("None shall pass");
}
?>
答案2
Sam 有答案。同样将它们放在带有 .htaccess 的目录中:
Authname Private
AuthType basic
require user noadmittance
如果他们知道 URL,这将阻止直接访问。您仍然可以使用 readfile() 从 PHP 脚本中读取它。
答案3
我找到了这本出色的指南:如何通过 PHP 提供大文件服务。
lighttpd 技巧特别有用 - 如果您的 PHP 恰好在 lighttpd 下运行,则脚本只需要设置“X-Sendfile”标头,lighttpd 就会为您读取并发送文件(并且它知道如何发送文件)。
更新:
Lighttpd 具有此功能,并且 Apache2 有一个 mod_xsendfile。
(引自NginX 文档)
答案4
一般来说,您应该在流式传输文件之前清理输出缓冲区,否则可能无法打开。如果您正在下载 EXE,代码签名证书可能已损坏。对于未进行代码签名的 EXE,这可能无关紧要,但这是确保代码签名仍然完好无损的最干净的方法,只需提供文件而不提供“额外”的标头/输出。
这与另一个答案很接近,但ob_clean();
已插入到标题之前。
function serve_file($filepath, $new_filename = null) {
$filename = basename($filepath);
if (!$new_filename) {
$new_filename = $filename;
}
$mime_type = mime_content_type($filepath);
ob_clean();
header('Content-type: ' . $mime_type);
header('Content-Disposition: attachment; filename="' . $new_filename . '"');
readfile($filepath);
}
用法:
serve_file($url, $filename);
例子:
$url = "example.exe";
$filename = "Example123.exe";
serve_file($url, $filename);