Kenneth Vogt Kenneth Vogt - 2 months ago 28
PHP Question

How do I access AWS S3 via PHP?

I have used Composer to install the AWS SDK for PHP per the getting started instructions found here. I installed it in my html root. I created an IAM user called "ImageUser" with the sole permission of "AmazonS3FullAccess" and captured its keys.

Per the instructions here, I created a file called "credentials" as follows:

[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY


Yes, I replaced those upper case words with the appropriate keys. The file resides in the hidden subdirectory ".aws" in the html root. The file's UNIX permissions are 664.

I created this simple file (called "test.php" in a subdirectory of my html root called "t") to test uploading a file to S3:

<?php
// Include the AWS SDK using the Composer autoloader.
require '../vendor/autoload.php';

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = 'testbucket';
$keyname = 'test.txt';

// Instantiate the client.
$s3 = S3Client::factory();

try {
// Upload data.
$result = $s3->putObject(array(
'Bucket' => $bucket,
'Key' => $keyname,
'Body' => 'Hello, world!',
'ACL' => 'public-read'
));

// Print the URL to the object.
echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
echo $e->getMessage() . "\n";
}
?>


Unfortunately, it throws a http error 500 at the line:

$s3 = S3Client::factory();


Yes, the autoloader directory is correct. Yes, the bucket exists. No, the file "test.txt" does not already exist.

According to the page noted above, "If no credentials or profiles were explicitly provided to the SDK and no credentials were defined in environment variables, but a credentials file is defined, the SDK will use the 'default' profile." Even so, I also tried explicitly specifying the profile "default" in the factory statement only to get the same results.

What am I doing wrong?

Answer

tldr; You have a mix of AWS SDK versions

  • Per the link you provided in your message (link) you have installed php sdk v3
  • Per your examples, you use PHP sdk v2

The v3 does not know about the S3Client::factory method so thats the reason it throws you the error. You can continue checking your link to check the usage https://docs.aws.amazon.com/aws-sdk-php/v3/guide/getting-started/basic-usage.html. There are a few methods to get the s3 client

  1. create a client - simple method

    <?php
    // Include the SDK using the Composer autoloader
    require 'vendor/autoload.php';
    
    $s3 = new Aws\S3\S3Client([
        'version' => 'latest',
        'region'  => 'us-east-1'
    ]);
    
  2. create a client - using sdk class

    // Use the us-west-2 region and latest version of each client.
    $sharedConfig = [
        'region'  => 'us-west-2',
        'version' => 'latest'
    ];
    
    // Create an SDK class used to share configuration across clients.
    $sdk = new Aws\Sdk($sharedConfig);
    
    // Create an Amazon S3 client using the shared configuration data.
    $s3 = $sdk->createS3();
    

once you have your client you can use your existing code (yes, this one is v3) to put a new object on s3 so you'll get something like

<?php
// Include the AWS SDK using the Composer autoloader.
require '../vendor/autoload.php';

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
$bucket = 'testbucket';
$keyname = 'test.txt';

// Instantiate the client.

-- select method 1 or 2 --

try {
    // Upload data.
    $result = $s3->putObject(array(
        'Bucket' => $bucket,
        'Key'    => $keyname,
        'Body'   => 'Hello, world!',
        'ACL'    => 'public-read'
    ));

    // Print the URL to the object.
    echo $result['ObjectURL'] . "\n";
} catch (S3Exception $e) {
    echo $e->getMessage() . "\n";
}
Comments