8

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?

2 Answers 2

3

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!

Sign up to request clarification or add additional context in comments.

3 Comments

With file_get_contents you are first moving the contents of the file to your server, and then to S3, thus not eliminating the extra traffic
Yes, you are correct. The server reads data before sending to S3 (extra traffic and extra time). I thought you have troubles to read data from Url. Did you find a solution to directly send content to S3? Thanks
This is not a correct solution, Bjorn wants to transfer the file directly from his remote server to S3, down vote.
0

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.

1 Comment

I have no control over the remote server/host. I already tried the suggested method, but even though it just requests the header, it considerably slowed the process down. I decided to move my server to Amazon as well (in the same availability zone as the bucket), and it is now up to speed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.