Reputation: 904
I want to upload a file from an external URL directly to an Amazon S3 bucket using the PHP SDK. I managed to do this with the following code:
$s3 = new AmazonS3();
$response = $s3->create_object($bucket, $destination, array(
'fileUpload' => $source,
'length' => remote_filesize($source),
'contentType' => 'image/jpeg'
));
Where the function remote_filesize is the following:
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";
}
However, it would be nice if I could skip setting the filesize when uploading to Amazon since this would save me a trip to my own server. But if I remove setting the 'length' property in the $s3->create_object function, I get an error saying that the 'The stream size for the streaming upload cannot be determined.' Any ideas how to solve this problem?
Upvotes: 8
Views: 8467
Reputation: 1630
You can upload file from url directly to Amazon S3 like this (my example is about a jpg picture):
1. Convert the content from url in binary
$binary = file_get_contents('http://the_url_of_my_image.....');
2. Create an S3 object with a body to pass the binary into
$s3 = new AmazonS3();
$response = $s3->create_object($bucket, $filename, array(
'body' => $binary, // put the binary in the body
'contentType' => 'image/jpeg'
));
That's all and it's very fast. Enjoy!
Upvotes: 3
Reputation: 714
Do you have any control over remote server/host?. If so you could set up a php server to query the file locally and pass the data to you.
If not, you could use something like curl to inspect the header like so;
$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);
This way, you are using a HEAD request, and not downloading the whole file -- still, you depend on the remote server send a correct Content-length header.
Upvotes: 0