26/06/2018 - PHP, SYMFONY
If you wish to upload files to AWS S3 buckets within Symfony applications by using AWS SDK for PHP library, you can use example below. In this example we are going to upload a video file. For more details read Get an Object Using the AWS SDK for PHP page.
First of all we want prevent the content of the buckets and its folders from being listed in browsers. To provide this feature we need to add a "Bucket Policy" to the bucket. If you navigate to "Permissions -> Bucket Policy" tab, at the bottom of the page you will see "Policy generator" button. If you use that button, you can generate an approprita policy. If you don't want, you can just copy and paste policy below. Assume that our bucket is my-videos
and we want public to have a GetObject
permissions. Note: Make sure that the "Public access" block for "Everyone" option has no permissions set at all.
{
"Version": "2012-10-17",
"Id": "Policy1530100021111",
"Statement": [
{
"Sid": "Stmt1530100001111",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-videos/*"
}
]
}
If you want you can make the whole bucket "private" by default and add 'ACL' => 'public-read'
property to putObject
method to make the objects "public" while uploading.
# User: These credentials belong to "AmazonS3FullAccess" user.
AWS_KEY=AMAZON000KEY
AWS_SECRET=AMAZON000SECRET
AWS_IMAGE_BUCKET=my-images-bucket
parameters:
# AWS SDK
aws_sdk:
version: 'latest'
region: 'eu-west-2'
credentials:
key: '%env(AWS_KEY)%'
secret: '%env(AWS_SECRET)%'
services:
_defaults:
autowire: true
autoconfigure: true
public: false
...
Aws\Sdk:
arguments:
- '%aws_sdk%'
declare(strict_types=1);
namespace App\Util\Aws;
use Aws\Sdk;
abstract class AwsUtil
{
protected $sdk;
public function __construct(Sdk $sdk)
{
$this->sdk = $sdk;
}
}
declare(strict_types=1);
namespace App\Util\Aws;
use App\Exception\AwsUtilException;
use Aws\S3\Exception\S3Exception;
class AwsS3Util extends AwsUtil
{
public function putObject(string $bucket, string $path, string $name): string
{
try {
$client = $this->sdk->createS3();
$result = $client->putObject(['Bucket' => $bucket, 'Key' => $name, 'SourceFile' => $path]);
$client->waitUntil('ObjectExists', ['Bucket' => $bucket, 'Key' => $name]);
return $result['ObjectURL'];
} catch (S3Exception $e) {
throw new AwsUtilException($e->getMessage());
}
}
}
putObject('my-videos', '/local/path/app/hello.mp4', 'hello.mp4')
You can then use the URL in response to access the video.