1

最初に、私はヘッダーの使用と出力バッファーで遊んでいる初心者であることを伝えたいと思います。そのため、liferay 用の php ポートレットを開発していますが、ファイルのダウンロードに問題があります。「a href」で簡単にやろうとしましたが、Apacheが更新されるまでphp経由でアップロードされたファイルが利用できないという問題があるため、header()関数で別の方法を試しました。

だから私は私の問題を説明しようとします。シンプルなphpプロジェクトで次のコードを試したところ、うまくいきました:

    <?php

$path = "/mysecretdir/upload/"; // change the path to fit your websites document structure
$fullPath = $path.$_GET['download_file'];

if ($fd = fopen ($fullPath, "r")) {

    $fsize = filesize($fullPath);

    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);

    switch($ext) {

        case "pdf":
            $ctype = "application/pdf";
            break;
        case "exe":
            $ctype = "application/octet-stream";
            break;
        case "zip":
            $ctype = "application/zip";
            break;
        case "doc":
            $ctype = "application/msword";
            break;
        case "xls":
            $ctype = "application/vnd.ms-excel";
            break;
        case "ppt":
            $ctype = "application/vnd.ms-powerpoint";
            break;
        case "gif":
            $ctype = "image/gif";
            break;
        case "png":
            $ctype = "image/png";
            break;
        case "jpeg":
            $ctype = "image/jpg";
            break;
        case "jpg":
            $ctype = "image/jpg";
            break;
        case "mp3":
            $ctype = "audio/mp3";
            break;
        case "wav":
            $ctype = "audio/x-wav";
            break;
        case "wma":
            $ctype = "audio/x-wav";
            break;
        case "mpeg":
            $ctype = "video/mpeg";
            break;
        case "mpg":
            $ctype = "video/mpeg";
            break;
        case "mpe":
            $ctype = "video/mpeg";
            break;
        case "mov":
            $ctype = "video/quicktime";
            break;
        case "avi":
            $ctype = "video/x-msvideo";
            break;
        case "src":
            $ctype = "plain/text";
            break;
        default:
            $ctype = "application/force-download";
    }

    header("Pragma: public");

    header("Expires: 0");

    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

    header("Cache-Control: private",false);

    header("Content-type: " . $ctype);

    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");

    header("Content-Transfer-Encoding: binary");

    //header("Content-length: $fsize");
    header("Cache-control: public"); //use this to open files directly    

    while(!feof($fd)) {
        echo fread($fd, 4096); 
    flush();
    }
}
fclose ($fd);
?>

index.php から href="download.php?download_file=/something/" で呼び出す

わかりましたが、今がポイントです。liferay ポートレットで使用すると、ファイルが奇妙になります。生成された HTML ファイル全体を、作成されたファイルに入れます。だから壊れた。理由はわかりません。ヘッダーが他の場所から情報を送信しているかどうかはわかりませんし、それを修正する方法もわかりません。

私は解決策を何時間も探していましたが、ヘッダーに問題があると思うので、どうにかしてヘッダーの「セッション」を作成する方法がわかりません。エコーなしでは、ファイルのコンテンツのみを印刷し、他のプロジェクトで印刷するため、ポータルの一部としてではなく、より単純なphpアプリが機能します! しかし、多分私は間違っています。

誰かが私を助けてくれますか?何かアドバイスはありますか?

4

2 に答える 2

1

特定のphpポートレットの問題についてはお手伝いできませんが(Liferayをphpで使用したことはありません)、ダウンロードしたファイルの「周り」に生成されたページ全体のHTMLを取得しているようです。これは、ポートレットをレンダリングするだけで得られるものです。ポートレットは常に HTML ページに埋め込まれているため、ポートレットの標準レンダリング出力を使用して HTTP レベルで特定のヘッダーを提供することはできません。

必要なのはserveResource、ポートレットのライフサイクル フェーズです。これにより、ページの一部ではないコンテンツを提供できますが、ダウンロードと HTTP ヘッダーを完全に制御できます。PHPポートレットでそれを行う方法は、あなたに任せる必要があります。

編集(追加情報):コメントで尋ねたように、上記で提案した serveResource の代わりに、 state=exclusive を使用して同じトリックを行うことについて話している古い(適応する必要があるかもしれない) Wiki記事を見つけました。これが記事の古さによるものなのか、それとも PHP ポートレットがそのライフサイクルをサポートしていないためなのかはわかりませんが、関連する記事やリンクされた記事で何かを見つけることができるかもしれません。注: serveResource は (私の間違いでなければ) p_p_lifecycle=2 パラメーターを生成しますが、この例では p_p_lifecycle=0 (レンダリング) と p_p_state=exclusive を使用しています。これが要件に合っているかどうか試してください

ただし、コードが安全ではなく、ハードコーディングされすぎているという Marc B のコメントを考慮してください。根本的な問題に対するより良い解決策があります。たとえば、Liferay はドキュメント ライブラリを提供して、すぐにファイルをアップ/ダウンロードできます。そして、それにはこれらの問題はありません。

于 2012-09-17T14:33:05.420 に答える
0

スペースまたはその他の文字で PHP ファイルを開始すると、ヘッダーが機能せず、表示/ダウンロードが失敗します。<?phpタグの前に何もないことを確認してください。

それ以外は、これでうまくいくはずです (ブラウザでエラーが発生しない場合)。

一方、実際の PHP コードが表示される場合、サーバーは PHP をサポートしていません。

于 2012-09-17T14:22:10.017 に答える