PHP下载PDF总是导致不支持文件类型的损坏文件 [英] PHP Download PDF always results in not supported file type of damaged file

查看:152
本文介绍了PHP下载PDF总是导致不支持文件类型的损坏文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的网站的用户下载文件。除此之外,我想把它烧成一个我创建/使用的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& (Content-Type:application / octet- (Content-Type:application / download);
header(Content-Description:File Transfer);
header(Content-Length:)。 filesize($ file));
flush(); //这并不重要
$ fp = fopen($ file,r);
while(!feof( ($ fp)){
echo fread($ fp,65536);
flush(); //这对大量下载至关重要
}
fclose($ fp);
?>

这有效,但我想让我的框架继续工作。是使用我的框架的代码流,链接href是href =/ myApp / downloadz?type ='resume'& id ='8':

url被apache重写并转到index.php,它是我的前端控制器:

 <?php 
class Foo {
static public test($ classname)
{
if(preg_match( / \\\\ /,$类名))
{
$路径= str_replace函数( \\,‘/’,$类名);
}
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加载一些配置文件

然后,

 函数handleRequest()
{
$ request = new \controller\Request();
$ cmd_r = new \commands\common\CommandResolver();
$ cmd = $ cmd_r-> getCommand($ request);
$ presenter = $ cmd-> execute($ request); $!
$ b if(!$ request-> getProperty('ajax')&&!is_a($ cmd,'\ commands \Download\DownloadCommand')){
echo $ this-> handleRender($ request,$ presenter);






$ b

这里只需要注意getCommand并检查文件存在并使用反射

然后调用$ cmd-> execute,并且此时我们调用DownloadzCommand :: execute,

 函数execute(\controller\Request $ request){

parent :: execute($ request);

if($ this-> request-> getProperty(type)==resume|| $ this-> request-> getProperty(type)== coverLetter){
$ this-> handleJobApplicationDownload();


$ b私有函数handleJobApplicationDownload(){
if(!$ this-> loggedInMember){
exit;
}

尝试{
$ idobj = new \ mapper \IdentityObject();
$ jobApplication = \domain\JobApplication :: produceOne($ idobj-> field(jobApplication.jobApplicationId) - > eq($ this-> request-> getProperty(id)) ) - >字段(jobApplication.jobId) - > eq(jobs.jobId,false) - >字段(business.businessId) - > eq(jobs.businessId,false) - >字段(jobApplication.dateApplicationViewed) - > isnull(,false),null,JobBusinessJoin);

//在这里获取jobApplication是合法的 - 现在确保已登录的成员是该业务的招聘人员
$ idobj = new \mapper\IdentityObject();
$ business = \domain\Business :: produceOne($ idobj-> field(businessId) - > eq($ jobApplication-> getState(businessId)));

if(!$ business-> isRecruiter($ this-> loggedInMember-> getId())){
exit;
if else $ {$ b $ if($ this-> request-> getProperty(type)==resume){
if($ path = $ jobApplication-> getState (resumeUploadPath)){
//有一个简历路径,将它移动到
$ fullPath =common / jobs / resumes /\".$路径上;

$ tempDest =commands / Downloadz / $ path;
副本($ fullPath,$ tempDest);
} else {
exit;
}
elseif($ this-> request-> getProperty(type)==coverLetter){
if($ path = $ jobApplication-> getState( coverLetterUploadPath)){
//有一个coverLetter路径,将它移动到
$ fullPath =common / jobs / coverLetters /\".$路径上;
} else {
exit;
}
}
}
} catch(\base\ObjectDoesNotExistException $ e){
echonope;


$ b 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(); //这并不重要。
$ fp = fopen($ file,r);
while(!feof($ fp)){
echo fread($ fp,65536);
flush(); //这对大量下载至关重要
}
fclose($ fp);

unlink($ path);

}

此时发生下载。我打开文件,但它被损坏。



注意,即使是简单的文本文件也会发生同样的情况。



另外,即使我跳过文件复制部分,并且只将该文件原本放在命令/ Downloadz目录中,它也不起作用。



任何想法?

解决方案



  $ fp = fopen($ file,r); 
while(!feof($ fp)){
echo fread($ fp,65536);
flush(); //这对大量下载至关重要
}
fclose($ fp);

使用 readfile()

 的ReadFile($文件); 


I'm trying to allow the user of my site to download files. More than this, I'd like to bake this into a Front Controller framework that I've created/am using. I can get the download to occur but when trying to open the file Adobe Reader always gives an error saying the file is of an unsupported type or it is damaged. In My Downloads it says the size of the file is 0KB which is obviously wrong, so it is getting damaged I guess. I don't know why though.

I CAN get the download to work but skipping my Front Controller framework and just having it directly run a download script. This script looks like this and is called downloadManager.php and is called from a link with 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);
?>

This works, but I'd like to keep my framework working. This is the code flow using my framework, with link href being href="/myApp/downloadz?type='resume'&id='8'":

The url gets rewritten by apache and goes to index.php which is my front controller:

<?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();
?>

Which leads to a Controller:

static function run()
{
    $instance = new Controller();
    $instance->init();
    $instance->handleRequest();
}

init sets up a PDO MySQL connection, and also loads some config files using Simple_XML_Load

Then,

    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);
    }
}

Only thing to note here is getCommand and checks if files exist and uses reflection

So then $cmd->execute is called and at this point we call 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);

}

And at this point the download occurs. I open the file though, and it is damaged.

A note, same thing happens even for a simple text file.

Also, it also doesn't work even if I skip the file copying part and just have the file originally in commands/Downloadz directory.

Any ideas?

解决方案

Instead of using:

$fp = fopen($file, "r");
while (!feof($fp)) {
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
}
fclose($fp);

Use readfile()

readfile($file);

这篇关于PHP下载PDF总是导致不支持文件类型的损坏文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆