Amazon S3 php ile kuvvet-indir

8 Cevap php

Ben AWS S3'ten http://code.google.com/p/amazon-s3-php-class/ zorlamak-dowload dosyaları kullanmak çalışıyorum. Ben insanların "play" veya istediğiniz bir mp3 var "indirin." Varsayılan olarak bunu tarayıcıda oynamaya başlar s3 doğrudan dosyaya erişmek zaman. Ben aslında indirmek için bir seçenek eklemek gerekir. Ben Googled ve hiçbir şey ile geldi bulduk. Ben kavramsal gerçekleşmesi gerektiğini biliyorum ama bunu php üretmek için nasıl bilmiyorum. Eki: Ben Content-Bırakma için başlıklarını değiştirmeniz gerekir biliyorum. Herhangi bir yardım büyük mutluluk duyacağız.

Thanks, Michael

8 Cevap

Şimdiye kadar söz edilmiştir php scriptler Tamam çalışır, ancak ana olumsuz sitenizde bir ziyaretçi bir dosya istediğinde, her zaman, kendi sunucuları S3'ten yükleyin ve ardından tarayıcı bu verileri röle olacaktır. Düşük trafik siteler için, muhtemelen büyük bir anlaşma değil, ama yüksek trafik olanlar için, kesinlikle kendi sunucuları aracılığıyla her şeyi çalıştıran önlemek istiyor.

Neyse ki, S3 indirmek zorunda dosyalarınızı ayarlamak için oldukça düz ileri bir yolu var. Ve sen haklısın - sadece (sadece içerik-eğilim belirleme, bazı tarayıcılarda çalışır, ancak her iki ayar tüm tarayıcılarda çalışması gerekir) içerik türü ve içerik-eğilim ayarlamak istiyorum.

Bu kod undesigned gelen Amazon S3 PHP sınıfını kullanarak olduğunuzu varsayarak:

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

?>

Şimdi tüm dosyaları indirmek zorunda kalacak. Siz değişiklik görmek için önbelleği temizlemek gerekebilir. Ve tabii ki, aslında tarayıcıda "inline" yüklenmesine istiyorsun herhangi bir dosya üzerinde yapmak yok.

Bu çözüm ile güzel kısmı doğrudan medya dosyalarını yüklemek başvurular, içerik-türü veya içerik eğilim umurumda değil, siz hala tarayıcıda dosyalarını çalabilir ve (gibi Flash'ı bir mp3 çalar diyelim) olduğunu aynı dosyayı indirmek için bir link. Kullanıcı zaten flaş dosyası yüklenirken bitmiş, onlar büyük olasılıkla hala indir süper hızlı olması anlamına gelir ve hatta size S3'ten herhangi bir ekstra bant genişliği ücretleri maliyeti olmayacak ki, onların önbellekte olacak.

Amazon şimdi bu sorunu çözmüş ve imzalı istekleri ile bir istek başına temelinde başlıkları geçersiz kılma sağlar etti:

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

w00t!

Yani böyle olması benim yukarıdaki örnek değiştirin


<?php

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

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

exit();

?>

Şimdi size dünyayı size S3 koymak her dosyaya erişim vererek değil, ama bu çalışması gerektiğini, böylece orada bazı doğrulama koymak isteyeceksiniz.

Sadece s3 üzerinde dosyanın meta bunu ekleyin:

Content-Disposition: attachment; filename=FILENAME.EXT
Content-Type: application/octet-stream

php sadece sunucu değil istemci dosyayı indirmek istiyorsunuz. php istemci üzerinde bir şey yapmaz, hatırlıyorum, sadece içeriği (html, javascript, css, xml, neyse ...) döndürür

[Değiştir: netlik eklenmiş]: php ses içeriği hizmet edebilir, ama aynı zamanda bir web sayfası ve ses hizmet etmek istiyorum. Bu istemci davranışını elde etmek için, web sayfasının html veya javascript dayalı dosya talep müşteri almak zorunda.

Yani dosyayı indirmek için müşteri almak zorunda. Örneğin, s3 dosyanın url sayfada bir iframe var. Iframe görünmez yapmak için css kullanın. Bu sayfayı oluşturmak ve indirmek ve oynamak mp3 gerekir.

Aksi takdirde, sayfa yüklendiğinde bir indirme tekme javascript kullanarak içine bakmak. Bunun mümkün olup olmadığından emin değilim.

Ayrıca kayda değer Eğer S3 dosyaları için sabit-set başlıklarına mümkün olmaktadır. Eğer belirli bir dosyayı zorla indirmek için gerekirse Örneğin, bu dosya için uygun başlıkları ayarlayabilirsiniz. Akarsu varsaymak, ve-indir zorlamak veya PHP ile php / fputs ve kuvvet-indir kullanmak için bant genişliğini harcamak için ayarlanmış bir ikincil dosyayı sahip ya olduğu gibi.

Sadece bu bir katkı göndermek isteyen, Alex Neth bu başvuru üzerine doğru, ama Amazon'un kendi AWS PHP SDK2 kullanarak, bir bağlantı yeterli bilgi hissetmiyorum. Verileri bu şekilde çağırmak için bir temel (denenmemiş) yöntemini açıkladık Aşağıda, S3 Client yapmak için S3 Fabrika Yöntemini veya AWS Hizmet Builder kullanabilirsiniz.

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

Daha sonra PHP'nin başlığını kullanabilirsiniz ("Konum: $ url"); bir kuvvet download MP3 dosyasına ziyaretçinin yönlendirmek için, bu tarayıcıda oynayan önlemek gerekir, unutmayın, ben oldukça sık ResponseContentType kullanın ama AWS ile ResponseContentDisposition hiç kullanmadım (bu dokümanlar göre çalışmalıdır .)

Bir fonksiyon içine örnek dönüştürerek kolay olmalı, hatta $ kova $ anahtarı geçebileceği, $ gibi 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"));

?>

Eğer bunu anladım değil varsa UYARI, bu şu anda burada bulunan (7 Nisan 2014) http://aws.amazon.com/sdkforphp/ Bu kod çoğunlukla sahte kod ve aslında aynı işi yapmak için bazı ek verdiği gerekebilir AWS PHP SDK 2 gerektirir Bu bellekten referans ediyorum.

Amazon'un S3 hosting hiç denemedim, ama orada. Htaccess dosyalarını kullanarak erişim yok? Sonra bu giriş ile bütün bir dizin için Content-Type ve Content-Disposition ayarlayabilirsiniz:

<IfModule mod_headers.c>
    <FilesMatch "\.(mp3)$">
            ForceType audio/mpeg
            Header set Content-Disposition attachment
    </FilesMatch>
</IfModule>