0

私のサイトのユーザーがファイルをダウンロードできるようにしようとしています。これ以上に、これを作成/使用しているフロントコントローラーフレームワークに焼き付けたいと思います。ダウンロードを実行できますが、ファイルを開こうとすると、Adobe Readerは、ファイルがサポートされていないタイプであるか、ファイルが破損しているというエラーを常に表示します。My Downloadsでは、ファイルのサイズが0KBと表示されていますが、これは明らかに間違っているため、破損していると思います。理由はわかりませんが。

ダウンロードを機能させることはできますが、フロントコントローラーフレームワークをスキップして、ダウンロードスクリプトを直接実行するだけです。このスクリプトは次のようになり、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'&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はPDOMySQL接続をセットアップし、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-> executeが呼び出され、この時点で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);

}

そして、この時点でダウンロードが発生します。しかし、ファイルを開くと、破損しています。

注意、単純なテキストファイルでも同じことが起こります。

また、ファイルのコピー部分をスキップして、元々commands/Downloadzディレクトリにファイルを置いても機能しません。

何か案は?

4

2 に答える 2

1

使用する代わりに:

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

使用するreadfile()

readfile($file);
于 2013-01-26T16:15:39.810 に答える
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();

これは私のために働きます。

于 2013-05-15T08:08:13.667 に答える