我正在尝试允许我网站的用户下载文件。更重要的是,我想将其烘焙到我已创建/正在使用的Front Controller框架中。我可以进行下载,但在尝试打开文件时,Adobe Reader始终会发出错误消息,指出该文件属于不受支持的类型或已损坏。在我的下载中,它说文件的大小是0KB,这显然是错误的,所以我猜它会受到损坏。我不知道为什么。
我可以让下载工作但跳过我的Front Controller框架并让它直接运行下载脚本。这个脚本看起来像这样,名为downloadManager.php,从一个链接调用href =“/ myApp / downloads / downloadManager.php:
<?php
header("Content-Type: application/octet-stream");
$file = "eZACKe_1359081853_Week Three Sprints & Hurdles Workout 24th - 28th of Sept (1).pdf";
header("Content-Disposition: attachment; filename=" . $file);
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp)) {
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
?>
这很有效,但我想让我的框架保持正常运行。这是使用我的框架的代码流,链接href为href =“/ myApp / downloadz?type ='resume'&amp; id ='8'”:
url被apache重写并转到index.php,这是我的前端控制器:
<?php
class Foo {
static public function test($classname)
{
if(preg_match('/\\\\/', $classname))
{
$path = str_replace('\\', '/', $classname);
}
else
{
$path = str_replace('_', '/', $classname);
}
if (is_readable($path.".php"))
{
require_once $path .".php";
}
}
}
spl_autoload_register('\Foo::test');
\controller\Controller::run();
?>
导致控制器:
static function run()
{
$instance = new Controller();
$instance->init();
$instance->handleRequest();
}
init设置PDO MySQL连接,并使用Simple_XML_Load加载一些配置文件
然后,
function handleRequest()
{
$request = new \controller\Request();
$cmd_r = new \commands\common\CommandResolver();
$cmd = $cmd_r->getCommand($request);
$presenter = $cmd->execute($request);
if(!$request->getProperty('ajax') && !is_a($cmd, '\commands\Download\DownloadCommand')) {
echo $this->handleRender($request, $presenter);
}
}
这里唯一需要注意的是getCommand并检查文件是否存在并使用反射
然后调用$ cmd-&gt;执行,此时我们调用DownloadzCommand :: execute,
function execute(\controller\Request $request) {
parent::execute($request);
if($this->request->getProperty("type") == "resume" || $this->request->getProperty("type") == "coverLetter") {
$this->handleJobApplicationDownload();
}
}
private function handleJobApplicationDownload() {
if(!$this->loggedInMember) {
exit;
}
try {
$idobj = new \mapper\IdentityObject ();
$jobApplication = \domain\JobApplication::produceOne($idobj->field("jobApplication.jobApplicationId")->eq($this->request->getProperty("id"))->field("jobApplication.jobId")->eq("jobs.jobId", false)->field("businesses.businessId")->eq("jobs.businessId", false)->field("jobApplication.dateApplicationViewed")->isnull("", false), null, "JobBusinessJoin");
// get here the jobApplication is legit - now make sure the logged in member is a recruiter for this business
$idobj = new \mapper\IdentityObject ();
$business = \domain\Business::produceOne($idobj->field("businessId")->eq($jobApplication->getState("businessId")));
if(!$business->isRecruiter($this->loggedInMember->getId())) {
exit;
} else {
if($this->request->getProperty("type") == "resume") {
if($path = $jobApplication->getState("resumeUploadPath")) {
// have a resume path, move it over
$fullPath = "common/jobs/resumes/".$path;
$tempDest = "commands/Downloadz/$path";
copy($fullPath, $tempDest);
} else {
exit;
}
} elseif($this->request->getProperty("type") == "coverLetter") {
if($path = $jobApplication->getState("coverLetterUploadPath")) {
// have a coverLetter path, move it over
$fullPath = "common/jobs/coverLetters/".$path;
} else {
exit;
}
}
}
} catch(\base\ObjectDoesNotExistException $e) {
echo "nope";
}
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . $path);
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($path));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp)) {
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
unlink($path);
}
此时下载发生。我打开文件,它已经损坏了。
注意,即使对于简单的文本文件也会发生同样的事情。
此外,即使我跳过文件复制部分并且只是将文件放在命令/ Downloadz目录中,它也不起作用。
有什么想法吗?
答案 0 :(得分:1)
而不是使用:
$fp = fopen($file, "r");
while (!feof($fp)) {
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
readfile($file);
答案 1 :(得分:1)
我有同样的问题,但在阅读http://davidwalsh.name/php-force-download后,现在正在运作。
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Type: application/pdf');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($filepath)) . ' GMT');
header('Content-disposition: attachment; filename=' . $pathinfo['filename'] . '.pdf');
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($filepath)); // provide file size
header('Connection: close');
readfile($filepath);
exit();
这适合我。