0

サーバーにファイルを単純に保存するプロジェクトがあります。誰かがファイルをダウンロードしたい場合、中間コントローラー (Zend フレームワーク) を介して要求を渡して、ファイルを保護する必要があります。

誰かがファイルを要求すると、ファイルはクライアント ブラウザにダウンロードされますが、私のすべてのテストでは、ファイルは常に破損して返されます (ただし、バイトに対して適切なサイズです)。誰かが私がここで間違っていることを教えてもらえますか?

 public function downloadAction() {
    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender(true);

    $files = new Application_Model_DbTable_Files();

    $file = $files->getFileForDownload($this->_getParam('id'), Zend_Auth::getInstance()->getIdentity()->id);

    $config = Zend_Registry::get('config');

    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender();


    if (file_exists($config['mindful']['path'] . $file)) {
        $this->getResponse()->setHeader('Content-type', 'application/octet-stream');
        $this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false);
        $this->getResponse()->setBody(readfile($config['mindful']['path'] . $file));
    }
}

ご覧のとおり、Zend メソッドと標準 PHP の両方で試してみました。これらはどちらも同じ結果をもたらします。

助けてくれてありがとう!

リック

4

2 に答える 2

2

多くのフレームワークでのファイルのダウンロードで問題を引き起こす可能性のあるものの1つは、失われることです。\ nこれらは通常、PHPの?>の後に発生し、データとともに予期しない\nを送信することになります。これらの\nは、HTMLを送信する場合は完全に無害ですが、他のファイルは破損します。

PHPスクリプトでは、PHPタグを閉じる必要はありません。また、PHPタグを閉じないことをお勧めします。例外は、PHPテンプレートを(ビューで)使用している場合で、明らかにそれらを閉じる必要があります。

  • アクセスしているコントローラー(コントローラーを含む)が使用するすべてのモデルとコンポーネントの?>タグを削除します
  • 同じファイルの<?phpタグの前に入力がないことを確認してください
  • このアクションのレイアウトとビューのレンダリングが無効になっていることを確認してください(正しく実行されているようです)
于 2013-02-27T17:28:04.247 に答える
1

readfileファイルの内容を返すのではなく、すぐに出力します。戻り値はバイト数であるため、これは現在応答本文に追加されています。これがおそらく破損の原因です。

readfile最初にヘッダーを送信し、それを直接呼び出すことで、引き続き使用できます。

$this->getResponse()->setHeader('Content-type', 'application/octet-stream');
$this->getResponse()->setHeader('Content-Disposition', 'inline; filename=' . basename($file), false);
$this->getResponse()->sendHeaders();

readfile($config['mindful']['path'] . $file);

または、ファイルが非常に小さい場合は、現在のアプローチに固執してfile_get_contents代わりに使用できます。

$this->getResponse()->setBody(file_get_contents($config['mindful']['path'] . $file));

これらのアプローチはいずれもキャッシュを提供しないことに注意してください(たとえば、ヘッダー以降に変更された場合の処理​​)。

X-Sendfileの使用を検討することもできます。これは、よりメモリフレンドリーで、キャッシュヘッダーを処理します。

于 2013-02-27T17:28:25.503 に答える