How to handle files in AWS S3 using FlySystem with Slim & Erdiko 2

Nearly every project needs to handle files, sometimes just locally in the same server. Other times we need to integrate service like AWS S3 or DropBox, and there is when we have to start researching their API and/or looking for good libraries for those services.

What if, instead of using different libraries from scratch, we can handle those services at the same time with an awesome package called FlySystem?

This package League/FlySystem has as many drivers that am I sure that will satisfy any case, also is necessary to mention that this package is used for the most popular frameworks as Laravel, Symfony, Zend, CakePHP, etc, you can see other integrations here.

To show how to integrate this awesome package we will use Erdiko 2. Erdiko is running the Slim framework under the hood, so it will work the same way with the Slim skeleton.

Erdiko 2 quick setup

#cd YOUR_PROJECTS_ROOT

composer create erdiko/erdiko erdikoaws 2.0.0-beta1
cd erdikoaws
docker-compose up &

Install League/FlySystem and AWS S3 driver

Let’s start to install the Flysystem package into our Erdiko application.

composer require league/flysystem

Also is necessary install the AWS S3 provider for FlySystem

composer require league/flysystem-aws-s3-v3

Setup FlySystem and AWS S3 credentials

Create a FlySystem config file into config folder and set up our AWS S3 config.
If you don’t have an account on AWS S3 you can follow this Sign Up For Amazon S3 to get an account.

#config/flysystem.php
return 
[
    'credentials' => [
        'key'    => 'your-key',
         'secret' => 'your-secret',
    ],
    'region' => 'your-region',
    'version' => 'latest|version'
];

We don’t forget to include the new configuration file into settings PHP File

#bootstrap/settings.php
return
[
    'settings' => [
        'fs' => require getenv('ERDIKO_ROOT').'/config/flysystem.php',
    ]
]

Include FlySystem into Erdiko application with Dependency Injection

Then we need to initialize the library into our dependencies PHP file.

#bootstrap/dependencies.php
// FlySystem
$container['fs'] = function ($container) {
    $client = Aws\S3\S3Client::factory($container->settings->get('fs'));

    $adapter = new League\Flysystem\AwsS3v3\AwsS3Adapter($client, 'your-bucket-name');
    $filesystem = new League\Flysystem\Filesystem($adapter);
};

Latest step and most important to set up AWS S3

For version 3 of AWS S3 is required config the IAM Permissions, here an example of the required configuration, for more information you can visit Getting Set Up – AWS Identity and Access Management

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1420044805001",
            "Effect": "Allow",
            "Action": [
                "s3:ListObjects",
                "s3:HeadObject",
                "s3:CopyObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:GetObjectAcl",
                "s3:PutObjectAcl",
                "s3:PutObject",
                "s3:CopyObject",
                "s3:UploadPart",
                "s3:CreateMultipartUpload"
            ],
            "Resource": [
                "arn:aws:s3:::your-bucket-name",
                "arn:aws:s3:::your-bucket-name/*"
            ]
        }
    ]
}

How to use FlySystem with Erdiko

Creating Controller

Our first method called form, it will be used to render our upload form, then we need to create the upload method to process the file uploaded and send it to our AWS S3 storage.

#app/controllers/Uploads
<?php

namespace app\controllers;

use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Http\UploadedFile;

class Uploads extends \erdiko\controllers\Web
{
    use \erdiko\theme\traits\Controller;

    public function getForm(Request $request, Response $response)
    {
        $view = 'upload/form.html';
        $themeData['theme'] = \erdiko\theme\Config::get($this->container->get('settings')['theme']);

        return $this->container->theme->render($response, $view, $themeData);
    }

    public function upload($request, $response)
    {
        $uploadedFiles = $request->getUploadedFiles();
        $uploadedFile = $uploadedFiles['fsfile'];

        $fs = $this->container->get('fs');
        $fs->write('path/to/aws/'.$uploadedFile->getClientFilename(), $uploadedFile));

        $view = 'upload/form.html';
        $themeData['theme'] = \erdiko\theme\Config::get($this->container->get('settings')['theme']);
        $themeData['page'] = ['message' => 'Success!'];

        return $this->container->theme->render($response, $view, $themeData);
    }
}

Creating upload form

At last, we just need to create view for the form to dispatch the Upload Controller.

#pages/upload.html
{% extends "page.html" %}

  {% block body %}
    <h1>Upload with FlySystem</h1>

    <!-- make sure the attribute enctype is set to multipart/form-data -->
    <form method="post" enctype="multipart/form-data" action="examples/upload">
    <p>
        <label>Add file (single): </label><br/>
        <input type="file" name="fsfile"/>
    </p>
    <p> <input type="submit"/> </p>
</form>
{% endblock %}

That’s all, now you can handle your files directly into AWS S3 or with any driver of your choice, here the list of the official supported drivers:

Conclusion

We hope you found this tutorial useful. If you have any questions, do leave a comment below. If you like our tutorial, please share it on your preferred social network, we need your support to continue.

Hopefully, this simple tutorial helped you with your development, so If you have questions or find any mistakes in above tutorial, do leave a comment below to let us know, thanks.

Next Post

Comments

See how we can help

Lets talk!

Stay up to date on the latest technologies

Join our mailing list, we promise not to spam.