05Eric's avatar

Laravel 5.1 Filesystem won't upload file

Hello, im having some trouble implementing filesystem right. Originally, i was using the simplest method i could find to upload a file to the server, and the code was the following:

$file       = $request->file("picture");
$filename   = date("Y-m-d-h-i-s") . "." . $file->getClientOriginalName();
$imageUrl   = "img/entries/". $fileName;
$file->move($folder, $fileName);

With this code, i saved the variable $imageUrl in the database and served it with asset($picture). Now i need to be able to change storage providers as needed (File storage has been moved to s3 in our production server, but i still need local access).

Switching between both disks is done via an environment variable, and i already have my s3 credentials like so:

's3' => [
            'driver' => 's3',
            'key'    => env("AWS_KEY" , ""),
            'secret' => env("AWS_SECRET", ""),
            'region' => env("AWS_REGION", ""),
            'bucket' => env("AWS_BUCKET", ""),
        ],

The code to save the image is:

$this->fileSystem->put($fileName, file_get_contents($file));

However, on my local driver nothing gets saved. I already tried to change $file with $file->getRealPath inside file_get_content, replaced file_get_contents with File::get($file) and also changed $fileSystem with Storage::disk("") facade, but still nothing works (No error is thrown, app just keeps going without saving the image).

When i change the driver to use amazon s3, i get the following error when i try to upload an image:

exception 'BadMethodCallException' with message 'Call to a member function getStatusCode() on a non-object (NULL)' in /home/vagrant/Code/rob_backend/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php:254

ps: for the amazon s3 part, i already included the "league/flysystem-aws-s3-v3": "~1.0" listed on the documentation Anyone knows why i can't upload the file? i'm already out of ideas

0 likes
2 replies
phildawson's avatar
Level 26

@05Eric Well Illuminate\Filesystem\FilesystemManager uses v2 so I wouldn't have thought v3 would work as it's under the AwsS3v3 namespace.

use League\Flysystem\AwsS3v2\AwsS3Adapter as S3Adapter;
Before using the S3 or Rackspace drivers, you will need to install the appropriate package via Composer:
Amazon S3: league/flysystem-aws-s3-v2 ~1.0

I would start with the most basic test which should locally make a file storage/app/file.txt with the string Contents inside.

\Storage::disk('local')->put('file.txt', 'Contents');

Once that works to use s3 the steps are require the flysystem aws v2 package.

composer require league/flysystem-aws-s3-v2

Update config/filesystems.php with your details

        's3' => [
            'driver' => 's3',
            'key'    => 'your-key',
            'secret' => 'your-secret',
            'region' => 'your-region',
            'bucket' => 'your-bucket',
        ],

The swap local for s3 and see you should get the file save on s3

\Storage::disk('s3')->put('file.txt', 'Contents');

That's it really.

What you have actually uncovered is a slight bug in the flysystem-aws-s3-v3 code where it should really be checking if getResponse() is not null before testing the status code on this line.

if ($exception->getResponse()->getStatusCode() === 404) {

https://github.com/thephpleague/flysystem-aws-s3-v3/blob/master/src/AwsS3Adapter.php

    public function getMetadata($path)
    {
        $command = $this->s3Client->getCommand('headObject', [
            'Bucket' => $this->bucket,
            'Key' => $this->applyPathPrefix($path),
        ]);
        /** @var Result $result */
        try {
            $result = $this->s3Client->execute($command);
        } catch (S3Exception $exception) {
            if ($exception->getResponse()->getStatusCode() === 404) {
                return false;
            }
            throw $exception;
        }
        return $this->normalizeResponse($result->toArray(), $path);
    }
1 like
05Eric's avatar

Hello, thanks for the reply. Sorry for the late reply, was busy with some stuff at work.

Following what you said i was able to upload files locally (problem was an error with my upload path configuration in the local driver). Changed it to public_path() instead of storage_path() to make it available to my API endpoint.

Regarding the s3 driver, i changed everything to v2 library and i started to get a blank page with no error. After looking through the FilesystemManager source, i found that it required the adapter in v3, so that was causing the fatal crash.

Right now i'm using Laravel's master branch (5.1) just to be able to use the "withoutMiddleware" trait for my tests, but since it's not fully on stable release, i'm assuming that maybe the bug is related to the framework itself or some new implementation in the way.

For now, i'm gonna stick to local storage and wait for the 5.1 stable release to try and modify my storage engine to s3

Please or to participate in this conversation.