GatesPlan
GatesPlan

Reputation: 497

Laravel Storage facade asset() with wrong URL generation

I've been working on my project and just can't get it about Laravel Storage, specifically, visibility : public state of storage and its URL.

I do my uploaded file save via $filename = $file->store('mpmlimages', 'public');

From what I understand, when I put this $filename at asset() helper function, then I get my file URL.

In the current directory structure,

projectroot_folder
    |-- storage <-- this is actual storage, right?
    |       |--app
    |           |--public
    |                |--mpmlimages <-- this is file location
    |--public
          |--storage (symlink to storage\app\public) <-- it has shortcut icon.. I believe it's what laravel said simbolic link

Fails to work if
I use asset($filename), I got http://localhost:8000/mpmlimages/{GENERATED_FILENAME}.png

Works if
Manually changing the above URL to http://localhost:8000/storage/mpmlimages/{GENERATED_FILENAME}.png

...WHY?!?!?!?!?!? I can't understand what I've missed.

Upvotes: 0

Views: 2323

Answers (2)

Borisu
Borisu

Reputation: 848

The simplest solution is to prepend storage to the asset call:

asset("storage/{$filename}")

This way you don't have to create any symbolic links (besides the one you already have). To answer the original question: calling $file->store will use the public disk. If you check your config files you'll notice that the root of the public disk is 'root' => storage_path('app/public'), so that's why your files land in the storage/app/public folder.

Furthermore as a client you should only be able to access files in the public folder, hence the symbolic link to storage. That's the reason you don't use storage_path() as it will expose the webserver structure, instead of making a url the client can use. Example:

  • asset('storage/{$filename}') results in https:/server.com/storage/file.png
  • storage_path($filename) results in /var/www/server/storage/app/public/file.png

Upvotes: 2

Diogo Santo
Diogo Santo

Reputation: 789

That is due to the fact that asset() will point to public folder.
By creating a symbolic link from storage to public and using asset() you still need to tell laravel which of the folder/files in public you wish to access.

In you case is your symbolic link which will restructure the path tostorage\app\public`;

If you do a symbolic link from storage\app\public\mpmlimages to public\mpmlimages you can keep as asset('mpmlimages/<your img>')

What I think your symlink structure is

root
 |--public
 |    |--**S**storage (storage\app\public)
 |
 |--storage
       |--app
           |--public
                |--mpmlimages
                      |--img1.png
                      |--img2.jpeg
                      |-- etc

What your symlink should be in order for you to drop storage

root
  |--public
  |     |--**S**mpmlimages(storage\app\public\mpmlimages)
  |
  |--storage
        |--app
            |--public 
                  |--mpmlimages    
                        |--img1.png
                        |--img2.jpeg
                        |-- etc

Legend:

S -> As a Symlink indicator

To achieve this symlink relation, run:

ln -s storage/app/public/mpmlimages public/mpmlimages

Then if your $filename contains mpmlimages/<img>, all you need is:

asset($filename);

Upvotes: 1

Related Questions