2012-05-22 39 views
6

Desidero caricare un file da un URL esterno direttamente su un bucket Amazon S3 utilizzando l'SDK PHP. Sono riuscito a farlo con il seguente codice:Carica file esterno nel bucket AWS S3 utilizzando PHP SDK

$s3 = new AmazonS3(); 
$response = $s3->create_object($bucket, $destination, array(
    'fileUpload' => $source, 
    'length' => remote_filesize($source), 
    'contentType' => 'image/jpeg' 
)); 

Dove la funzione remote_filesize è la seguente:

function remote_filesize($url) { 
    ob_start(); 
    $ch = curl_init($url); 
    curl_setopt($ch, CURLOPT_HEADER, 1); 
    curl_setopt($ch, CURLOPT_NOBODY, 1); 
    $ok = curl_exec($ch); 
    curl_close($ch); 
    $head = ob_get_contents(); 
    ob_end_clean(); 
    $regex = '/Content-Length:\s([0-9].+?)\s/'; 
    $count = preg_match($regex, $head, $matches); 
    return isset($matches[1]) ? $matches[1] : "unknown"; 
} 

Tuttavia, sarebbe bello se potessi saltare l'impostazione della dimensione del file durante il caricamento di Amazon dal questo mi farebbe risparmiare un viaggio sul mio server. Ma se rimuovo l'impostazione della proprietà 'length' nella funzione $ s3-> create_object, viene visualizzato un errore che dice che 'La dimensione del flusso per il caricamento in streaming non può essere determinata'. Qualche idea su come risolvere questo problema?

risposta

0

Avete un controllo su server/host remoto ?. Se è così, puoi configurare un server php per interrogare il file localmente e passare i dati a te.

In caso contrario, è possibile utilizzare qualcosa come curl per ispezionare l'intestazione in questo modo;

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, 'http://sstatic.net/so/img/logo.png'); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_NOBODY, true); 
curl_exec($ch); 
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); 
var_dump($size); 

In questo modo, si sta utilizzando una richiesta HEAD, e non scaricare l'intero file - ancora, si dipende da server remoto invia una corretta intestazione Content-Length.

+0

Non ho controllo sul server/host remoto. Ho già provato il metodo suggerito, ma anche se richiede solo l'intestazione, ha rallentato notevolmente il processo. Ho deciso di spostare anche il mio server su Amazon (nella stessa zona di disponibilità del bucket) e ora è pronto per la velocità. – Bjorn

2

È possibile caricare file da URL direttamente ad Amazon S3 come questo (il mio esempio è di circa una foto jpg):

1. Converti i contenuti da URL in binario

$binary = file_get_contents('http://the_url_of_my_image.....'); 

2 . Creare un oggetto S3 con un corpo per passare la binario in

$s3 = new AmazonS3(); 
$response = $s3->create_object($bucket, $filename, array(
    'body' => $binary, // put the binary in the body 
    'contentType' => 'image/jpeg' 
)); 

Questo è tutto ed è molto veloce. Godere!

+3

Con file_get_contents devi prima spostare il contenuto del file sul tuo server e poi su S3, quindi non eliminare il traffico extra – Bjorn

+1

Sì, sei corretto. Il server legge i dati prima di inviare a S3 (traffico extra e tempo extra). Ho pensato che hai problemi a leggere i dati dall'URL. Hai trovato una soluzione per inviare direttamente contenuti a S3? Grazie –

+0

Sfortunatamente non – Bjorn

Problemi correlati