14

http://code.google.com/p/amazon-s3-php-class/を使用して、AWS S3 からファイルを強制的にダウンロードしようとしています。「再生」または「ダウンロード」してもらいたい mp3 があります。デフォルトでは、s3 でファイルに直接アクセスすると、ブラウザで再生が開始されます。実際にダウンロードするにはオプションを追加する必要があります。私はグーグルで検索しましたが、何も思いつきませんでした。私は概念的に何が起こる必要があるかを知っていますが、それをPHPで生成する方法がわかりません. ヘッダーを Content-Disposition: attachment に変更する必要があることはわかっています。どんな助けでも大歓迎です。

ありがとう、マイケル

4

12 に答える 12

21

Amazonはこの問題を解決し、署名されたリクエストを使用してリクエストごとにヘッダーをオーバーライドできるようになりました。

http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?RESTObjectGET.html

w00t!

于 2011-05-05T20:31:42.080 に答える
10

これまでに説明した php スクリプトは問題なく動作しますが、主な欠点は、サイトの訪問者がファイルを要求するたびに、独自のサーバーが S3 からファイルをロードし、そのデータをブラウザーに中継することです。トラフィックの少ないサイトでは、おそらく大したことではありませんが、トラフィックの多いサイトでは、すべてを独自のサーバー経由で実行することは絶対に避けたいでしょう.

幸いなことに、ファイルを S3 から強制的にダウンロードするように設定するかなり簡単な方法があります。そして、まさにその通りです - content-type と content-disposition を設定したいだけです (一部のブラウザーでは content-disposition を設定するだけで機能しますが、両方を設定するとすべてのブラウザーで機能するはずです)。

このコードは、Undesigned の Amazon S3 PHP クラスを使用していることを前提としています。

<?php

// set S3 auth and get your bucket listing

// then loop through the bucket and copy each file over itself, replacing the "request headers":
S3::copyObject($bucketName, $filename, $bucketName, $filename, "public-read", array(), array("Content-Type" => "application/octet-stream", "Content-Disposition" => "attachment"));

?>

これで、すべてのファイルが強制的にダウンロードされます。変更を確認するには、キャッシュをクリアする必要がある場合があります。そして明らかに、実際にブラウザーに「インライン」でロードしたいファイルに対しては、それを行わないでください。

このソリューションの良い点は、メディア ファイルを直接ロードするアプリケーション (たとえば、Flash の mp3 プレーヤーなど) がコンテンツ タイプやコンテンツの性質を気にしないことです。そのため、ブラウザでファイルを再生してから、リンクをクリックして、同じファイルをダウンロードします。ユーザーが既にファイルのフラッシュへのロードを完了している場合、そのファイルはキャッシュに残っている可能性が高いため、ダウンロードは非常に高速で、S3 から追加の帯域幅料金が発生することさえありません.

于 2009-12-21T21:01:59.137 に答える
4

これを s3 のファイルのメタデータに追加するだけです。

Content-Disposition: attachment; filename=FILENAME.EXT
Content-Type: application/octet-stream
于 2011-03-09T05:34:03.773 に答える
3

これへの貢献を投稿したいだけで、Alex Neth はこのリファレンスで正しいですが、Amazon 独自の AWS PHP SDK2 を使用して、リンクが十分な情報ではないと感じています。以下に、この方法でデータを呼び出すための基本的な (テストされていない) メソッドの概要を示します。S3 ファクトリー メソッドまたは AWS Service Builder を使用して S3 クライアントを作成できます。

<?php
// S3 Factory Method
/*use Aws\S3\S3Client;

$s3= S3Client::factory(array(
    'key'    => '<aws access key>',
    'secret' => '<aws secret key>'
));*/

// OR AWS Service Builder
use Aws\Common\Aws;

// Create a service builder using a configuration file
$aws = Aws::factory('/path/to/my_config.json');

// Get the client from the builder by namespace
$s3 = $aws->get('S3');

// Now lets create our request object.
$command = $s3->getCommand('GetObject',array(
    'Bucket'                        => 'your-bucket-name',
    'Key'                           => 'keyname',
    'ResponseContentType'           => 'application/octet-stream',
    'ResponseContentDisposition'    => 'attachment; filename="filename.mp3',
));
$url = $command->createPresignedUrl('+1 days');
?>

その後、PHP の header("Location: $url"); を使用できます。強制ダウンロードで訪問者を MP3 ファイルにリダイレクトするために、これによりブラウザでの再生が防止されます。注意してください、私は ResponseContentType を頻繁に使用しますが、AWS で ResponseContentDisposition を使用したことはありません (ドキュメントに従って動作するはずです)。 )。

このサンプルを関数に変換するのは簡単です。$bucket、$key、$force_download などを渡すこともできます。

<?php
use Aws\Common\Aws;

function gen_url($bucket,$key,$force_download=false){
    // OR AWS Service Builder (personal method to do this)

    // Create a service builder using a configuration file
    $aws = Aws::factory('/path/to/my_config.json');

    // Get the client from the builder by namespace
    $s3 = $aws->get('S3');
    $params = array(
        'Bucket'                        => $bucket,
        'Key'                           => 'keyname',
        'ResponseContentType'           => 'application/octet-stream',
        'ResponseContentDisposition'    => 'attachment; filename="filename.mp3',
    );

    if($force_download){
        $params['ResponseContentType'] = 'application/octet-stream';
        $params['ResponseContentDisposition'] = 'attachment; filename="'.basename($key).'"';
    }

    $command = $s3->getCommand('GetObject',$params);
    return $command->createPresignedUrl('+1 days');
}

// Location redirection to an MP3 force downlaod
header("Location: ".gen_url("recordings","my-file.mp3",true));
// Location redirection to a MP3 that lets the browser decide what to do.
header("Location: ".gen_url("recordings","my-file.mp3"));

?>

警告、わからない場合は、現在 (2014 年 4 月 7 日) ここにある AWS PHP SDK 2が必要ですhttp://aws.amazon.com/sdkforphp/このコードはほとんどが擬似コードであり、追加の調整が必要になる場合がありますこれをメモリから参照しているので、実際に機能させることができます。

于 2014-04-07T09:50:25.473 に答える
1
<?php
    require_once __DIR__.'/vendor/autoload.php';
    use Aws\Common\Aws;

    function gen_url($bucket,$key,$force_download=false){
        // OR AWS Service Builder (personal method to do this)


        $config = array(
                'key'    => '',
                'secret' => '',
        );

        // Create a service builder using a configuration file
        $aws = Aws::factory($config);

        // Get the client from the builder by namespace
        $s3 = $aws->get('S3');
        $params = array(
            'Bucket'                        => $bucket,
            'Key'                           => $key,
            'ResponseContentType'           => 'application/octet-stream',
            'ResponseContentDisposition'    => 'attachment; filename="'.$key,
        );

        if($force_download){
            $params['ResponseContentType'] = 'application/octet-stream';
            $params['ResponseContentDisposition'] = 'attachment; filename="'.basename($key).'"';
        }

        $command = $s3->getCommand('GetObject',$params);
        return $command->createPresignedUrl('+1 days');
    }

    $bucket = '';
    $filename = '';


    $url = gen_url($bucket,$filename,true);

    echo "\n".$url."\n\n";

上記のコードは機能します。S3 コンポーザーの依存関係をインストールし、オートロード ファイルにリンクし、キー/シークレットを構成に入れ、バケット/ファイル名を指定するだけです。

于 2014-06-06T14:47:37.060 に答える
1

また、S3 でファイルのヘッダーをハード設定できることにも言及する価値があります。たとえば、特定のファイルを強制的にダウンロードする必要がある場合、そのファイルに適切なヘッダーを設定できます。デフォルトでストリームを使用し、セカンダリ ファイルを強制ダウンロードに設定するか、帯域幅を消費して php/fputs を使用し、PHP 経由で強制ダウンロードするなどです。

于 2010-09-08T19:47:12.137 に答える
1

上記の例を次のように変更します


<?php

header('Content-Type: audio/mpeg');
header("Content-Disposition: attachment; filename={$_GET['file']};");

readfile("url to the file/{$_GET['file']}");

exit();

?>

ここで、S3 に置くすべてのファイルへのアクセスを世界に許可しないように、そこにいくつかの検証を入れたいと思うでしょうが、これはうまくいくはずです。

于 2009-05-21T10:36:48.297 に答える
0

php は、クライアントではなくサーバーにファイルをダウンロードするだけです。覚えておいてください、php はクライアント上で何もしません。コンテンツ (html、javascript、css、xml など) を返すだけです。

[編集: わかりやすくするために追加]: php は音声コンテンツを提供できますが、Web ページと音声を同時に提供したいとします。そのクライアントの動作を取得するには、Web ページの html または javascript に基づいてクライアントにファイルを要求させる必要があります。

したがって、クライアントにファイルをダウンロードさせる必要があります。たとえば、s3 上のファイルの URL を含む iframe をページに配置します。css を使用して、iframe を非表示にします。ページをレンダリングし、mp3 をダウンロードして再生する必要があります。

それ以外の場合は、ページの読み込み時に JavaScript を使用してダウンロードを開始することを検討してください。それが可能かどうかはわかりません。

于 2009-05-15T19:37:17.143 に答える
-3

私はAmazonのS3ホスティングを試したことがありませんが、そこで.htaccessファイルを使用するためのアクセス権がありませんか?次に、次のエントリを使用して、ディレクトリ全体のContent-TypeとContent-Dispositionを設定できます。

<IfModule mod_headers.c>
    <FilesMatch "\.(mp3)$">
            ForceType audio/mpeg
            Header set Content-Disposition attachment
    </FilesMatch>
</IfModule>
于 2009-05-20T23:12:30.397 に答える