Get CDN url from uploaded file via Storage

2019-08-02 19:13发布

问题:

I am using the Storage provider to upload files to rackspace like so...

$logo = $request->file('logo');
$content = fopen($logo->getRealPath(), 'r+');

\Storage::disk('cdn')->put('logo.png', $content);

Now, how can I get the url of the file above? I has been looking for a method in the API and it seems so impossible.

  • http://laravel.com/api/5.0/Illuminate/Filesystem/FilesystemAdapter.html
  • http://laravel.com/api/5.0/Illuminate/Filesystem/Filesystem.html

回答1:

I usually store the disk public URL in the config/filesystems.php file. For example:

    'google' => [
        'driver'        => 's3',
        'key'           => env('STORAGE_GOOGLE_KEY'),
        'secret'        => env('STORAGE_GOOGLE_SECRET'),
        'bucket'        => env('STORAGE_GOOGLE_BUCKET'),
        'base_url'      => 'https://storage.googleapis.com',
        'public_url'    => env('STORAGE_GOOGLE_PUBLIC_URL'),
    ],

Then in my model, I define a mutator for the field containing the file name:

public function getAvatarAttribute($value)
{
    // If avatar isn't a URL, generate it
    if (filter_var($value, FILTER_VALIDATE_URL) !== FALSE) {
        return $value;
    } else {
        $disk = config('filesystems.default');
        return config('filesystems.disks.'.$disk.'.public_url').'/avatars/'.$value;
    }
}

This allows me:

  1. To change the default disk at any time and immediately point all the references to my new disk.
  2. To store actual URLs in the database if required. In my case, avatars may come from OAuth or actual file uploads, so I need to cater for both.


回答2:

The issue here is the way the FlySystem adapter works.

For most operations it will just return a boolean indicating if an operation was successful or not. Even Laravel's FlySystem wrapper also doesn't keep track of paths, so a workaround would be to build the path yourself after a successful upload.

By using the filesystem configuration, we can come up with something like this:

$cdn_url = config('filesystems.disks.cdn.container').'/logo.png';

You get the picture.