7

I am migrating my code from AWS PHP SDK1 to SDK2 (https://github.com/aws/aws-sdk-php).

I have an image uploader. In my previous version, I would specify the Content-Type of my image like so:

$response = $this->s3->create_object(
                $bucket,
                $key,
                array(
                    'fileUpload'=>$file_resource,
                    'contentType'=>$mime, 
                    'acl' => AmazonS3::ACL_PUBLIC,
                    )
                );

This is my new version:

$response = $this->s3->upload(
                    $bucket, 
                    $key, 
                    $file_resource, 
                    'public-read',
                    array('params' => array('Metadata' => array('ContentType'=>$mime)))
                    );

I've tried different spellings of ContentType, in the S3 site it modifies the name to look like 'x-amz-meta-contenttype', while the value of 'Content-Type' is the default 'binary/octet-stream'.

I've also tried using the EntityBody feature, but same results:

$response = $this->s3->upload(
                    $this->bucket, 
                    $to, 
                    EntityBody::factory($file_resource), 
                    'public-read',
                    array('params' => array('Metadata' => array('ContentType'=>$mime)))
                    );

How do I set the content-type in this new API?

EDIT: I see somewhere in the documentation:

The AWS SDK for PHP will attempt to automatically determine the most appropriate Content-Type header used to store the object. If you are using a less common file extension and your Content-Type header is not added automatically, you can add a Content-Type header by passing a ContentType option to the operation.

First off, I am uploading simple images, yet according to my S3 dashboard, they are uploaded as 'binary/octet-stream'. About their second point, I've tried many combinations of arrays with 'ContentType' I'm not sure why it's not working...

3 Answers 3

18

At the end, this set of options worked:

array('params' => array('ContentType' => $mime))

No need for Metadata

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

Comments

4
  1. Well, using AWS\S3\S3Client::putObject() directly would definitely give you the control you need.

  2. File extensions need to be lowercase for the automatic detection to work.

  3. You can find the list of supported mime types in Guzzle\Http\Mimetypes.

4 Comments

1) From what I understand, upload() uses putObject behind the scenes, and is the recommended solution for file uploads. 2) Is it the file extension of the source, or of the destination name? My destination are lowercase, and the source are from PHP's temporary location for uploads - which I think have no extensions. 3) As expected, most image extensions are in that list.
The "source" file is $_FILES["avatar-file"]["tmp_name"], using PHP's handling of uploaded files. Correct me if I am wrong, but I believe the temp names generated by PHP do not keep the file extension...
I personally use finfo(FILEINFO_MIME_TYPE) to detect mime type, which I used to pass on to the AWS SDK. Worked fine until I switched to the new SDK.
It's a really strange. Works fine with aws-sdk-php-3.19.8, ubuntu 14.04. php-5.5.9
3

I believe the more recent AWS API versions require that the content type be set directly, e.g.

$client->putObject([
       'Bucket'      => $sBucket,
       'Key'         => $sPath,
       'SourceFile'  => $sData,
       'ContentType' => $sMimeType]);

Comments

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.