Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

S3 Batch / Parallel Upload Error with PHP SDK

I followed these codes to batch PutObject into S3. I am using the latest PHP SDK (3.x). But I am getting:

Argument 1 passed to Aws\AwsClient::execute() must implement interface Aws\CommandInterface, array given

$commands = array();
$commands[] = $s3->getCommand('PutObject', array(
    'Bucket' => $bucket,
    'Key'    => 'images/1.jpg',
    'Body' => base64_decode( 'xxx' ),
    'ACL' => 'public-read',
    'ContentType' => 'image/jpeg'
));

$commands[] = $s3->getCommand('PutObject', array(
    'Bucket' => $bucket,
    'Key'    => 'images/2.jpg',
    'Body' => base64_decode( 'xxx' ),
    'ACL' => 'public-read',
    'ContentType' => 'image/jpeg'
));

// Execute the commands in parallel
$s3->execute($commands);
like image 594
twb Avatar asked Jul 10 '15 06:07

twb


1 Answers

If you're using a modern version of the SDK, try building the command this way, instead. Taken straight from the docs; it should work. This is called the "chaining" method.

$commands = array();


$commands[] = $s3->getCommand('PutObject')
                ->set('Bucket', $bucket)
                ->set('Key', 'images/1.jpg')
                ->set('Body', base64_decode('xxx'))
                ->set('ACL', 'public-read')
                ->set('ContentType', 'image/jpeg');

$commands[] = $s3->getCommand('PutObject')
                ->set('Bucket', $bucket)
                ->set('Key', 'images/2.jpg')
                ->set('Body', base64_decode('xxx'))
                ->set('ACL', 'public-read')
                ->set('ContentType', 'image/jpeg');

// Execute the commands in parallel
$s3->execute($commands);

// Loop over the commands, which have now all been executed
foreach ($commands as $command)
{
    $result = $command->getResult();

    // Use the result.
}

Make sure you're using the latest version of the SDK.

Edit

It appears that the SDK's API has changed significantly in Version 3.x. The above example should work correctly in Version 2.x of the AWS SDK. For 3.x, you need to use CommandPool()s and promise():

$commands = array();

$commands[] = $s3->getCommand('PutObject', array(
    'Bucket' => $bucket,
    'Key'    => 'images/1.jpg',
    'Body' => base64_decode ( 'xxx' ),
    'ACL' => 'public-read',
    'ContentType' => 'image/jpeg'
));
$commands[] = $s3->getCommand('PutObject', array(
    'Bucket' => $bucket,
    'Key'    => 'images/2.jpg',
    'Body' => base64_decode ( 'xxx' ),
    'ACL' => 'public-read',
    'ContentType' => 'image/jpeg'
));


$pool = new CommandPool($s3, $commands);

// Initiate the pool transfers
$promise = $pool->promise();

// Force the pool to complete synchronously
try {
    $result = $promise->wait();
} catch (AwsException $e) {
    // handle the error.
}

Then, $result should be an array of command results.

like image 161
Will Avatar answered Dec 26 '22 11:12

Will