0
votes

I'm having problems setting the "Metadata" option when uploading files to Amazon S3 using the AWS SDK PHP v2. The documentation that I'm reading for the upload() method states that the the 5th parameter is an array of options...

*$options Custom options used when executing commands: - params: Custom parameters to use with the upload. The parameters must map to a PutObject or InitiateMultipartUpload operation parameters. - min_part_size: Minimum size to allow for each uploaded part when performing a multipart upload. - concurrency: Maximum number of concurrent multipart uploads. - before_upload: Callback to invoke before each multipart upload. The callback will receive a Guzzle\Common\Event object with context.*

My upload() code looks like this..

$upload = $client->upload(
  '<BUCKETNAME>',
  'metadatatest.upload.jpg',
  fopen('metadatatest.jpg','r'),
  'public-read',
  array('Metadata' => array(
    'SomeKeyString' => 'SomeValueString'
  ))
);

...and no meta data is set after upload.

If however I use putObject() as documented here, which I assume is a "lower level" method compared to upload()...

$putObject = $client->putObject(
  array(
    'Bucket' => '<BUCKETNAME>',
    'Key' => 'metadatatest.putobject.jpg',
    'Body' => file_get_contents('metadatatest.jpg'),
    'ACL' => 'public-read',
    'Metadata' => array(
      'SomeKeyString' => 'SomeValueString'
    )
  )
);

The meta data is successfully returned when I call getObject() or view the file directly in my browser when uploaded using putObject()

$getObject = $client->getObject(
  array(
    'Bucket' => '<BUCKETNAME>',
    'Key' => 'metadatatest.putobject.jpg'
  )
);

I would prefer to use the $client->upload() method as the documentation states

Upload a file, stream, or string to a bucket. If the upload size exceeds the specified threshold, the upload will be performed using parallel multipart uploads.

I'm not sure what I've missed?

1
This seems like it could be a bug. Please report it at github.com/aws/aws-sdk-php/issues. I would also mention the size of the objects you are uploading, because it may only be an issue with multipart uploads.Jeremy Lindblom
@JeremyLindblom Cheers I'll give that avenue a shot, The file was quite small as putObject() handles it fine.Scuzzy
@JeremyLindblom This isn't really a code bug, but a problem with how the documentation for that method is written. I also found it to be confusing until I looked at the actual source code. Maybe you guys can improve it with some examples that will clarify things.dcro
@dcro Ah, I can see how that can be confusing. Noted!Jeremy Lindblom

1 Answers

1
votes

There's really no difference in using upload() or putObject() if you don't do multipart uploads. You can have a look at the AWS PHP SDK source code but basically the upload method just calls putObject like this:

// Perform a simple PutObject operation
return $this->putObject(array(
    'Bucket' => $bucket,
    'Key'    => $key,
    'Body'   => $body,
    'ACL'    => $acl
) + $options['params']);

This isn't very clear in the SDK documentation, but you need to send the last parameter as an array with the key params and its value being a second array with the Metadata key and value like this:

$upload = $client->upload(
    '<BUCKETNAME>',
    'metadatatest.upload.jpg',
    fopen('metadatatest.jpg','r'),
    'public-read',
    array('params' => array(
        'Metadata' => array(
            'SomeKeyString' => 'SomeValueString'
    )))
);

However, I you could just use the putObject call to achieve the same thing.