1
votes

Aim

Hi, I am using laravel for a RESTful API. I would like to return users a URL to an image file. I am currently using local storage, but I have configured an Amazon S3 instance, and synced my images to it. My aim is to seamlessly switch between local storage and s3 by simply changing the first line in my config/filesystems.php:

'default' => 'public',

Details

I have configured laravel to access both the local disk and S3 via the config/filesystems.php file. As per the laravel instructions I have softlinked public/storage to storage/app/public. Here is the disks array from my config/filesystems.php:

    'disks' => [

//        'local' => [
//            'driver'    => 'local',
//            'root'      => storage_path('app'),
//        ],

        'public' => [
            'driver'        => 'local',
            'root'          => storage_path('app/public'),
            'visibility'    => 'public',
        ],

        's3' => [
            'driver'    => 's3',
            'key'       => '...',
            'secret'    => '...',
            'region'    => '...',
            'bucket'    => 'mybucket',
        ],
    ],

This is my folder hierarchy:

On Local Disk:

  • myLaravelApp/storage/mobile/backgrounds/
  • myLaravelApp/storage/mobile/closetimages/
  • myLaravelApp/storage/mobile/profileimages/

On S3

  • mybucket/mobile/backgrounds/
  • mybucket/mobile/closetimages/
  • mybucket/mobile/profileimages/

As I said earlier, I would like to seamlessly switch between local storage and s3 by simply changing the first line in my config/filesystems.php:

'default' => 'public',

and I was hoping to use the following function call to return data to the user:

return Storage::url('mobile/profileimages/12345.jpg');

When I make this call with s3 as default, the response is like this:

https://s3.amazonaws.com/mybucket/mobile/profileimages/12345.jpg

Which is brilliant! However when I make this call with default local storage, the response is:

/storage/mobile/profileimages/12345.jpg

Which is not even a complete URL :( What I would like to return is something like:

http://mywebapp/storage/mobile/profileimages/12345.jpg

But I would like the same call to work for both s3 and local storage so that I can switch seamlessly.

Am I using it incorrectly? It's frustrating because this is obviously a library/framework call so I would expect it to work, or at least to return a complete URL.

Thank you

1

1 Answers

4
votes

You can try something like this

function public_url($path = '')
{
    $fs = app('filesystem');

    if ($fs->getDriver()->getAdapter() instanceof \League\Flysystem\Adapter\Local) {
        return asset($fs->url($path));
    }

    return $fs->url($path);
}

You can use it like this

$assetUrl = public_url('mobile/profileimages/12345.jpg');