jontyjago's avatar

Uploading files and storing path in database

I'm struggling with uploading files and then easily accessing them.

I've configured the storage link so anything placed in storage/app/public is visible through http://example.com/storage/ however this is where I'm having problems

The following code in my controller

$path = $request->file('docfile')->store('public');

        return $path;

saves the files to the correct directory but the $path returned is

public/Y9GvrBuY6RG2thIrvjXWsrLZYOPn2u9fLNW1v268.png

so if I save this to the database and try to link to that later the file will not be found, as the storage folder is linked, not the public folder.

If I don't put a folder name in the controller:

$path = $request->file('docfile')->store('');

        return $path;

then the $path variable only contains the file name but it gets saved to storage/app so is not found by http://example.com/storage/. Using 'storage' as the folder in the controller would save the file to storage/app/storage.

What I would like is to save just the file name in the database and for the file to be saved in the correct location so it is visible from http://example.com/storage/

Going forward I would like to be able to configure a custom file structure like http://example.com/name/uploads but I need to get the basics right first!

0 likes
5 replies
viktorivanov's avatar

Hi @jontyjago , I was having the same issue with path including public/xxx_hash_xxx.jpg and what i did was to use basename($path) and prefix it with 'storage/' and then store the string to the db, eg. storage/xxx_hash_xxx.jpg.

But I'm curious to see the proper way as well :)

1 like
mushood's avatar

Okay, taking things step by step.

When you run this:

$path = $request->file('docfile')->store('public');

        return $path;

The file is stored in the right directory but the path is public/Y9GvrBuY6RG2thIrvjXWsrLZYOPn2u9fLNW1v268.png

However, you need to path to be

storage/app/public/Y9GvrBuY6RG2thIrvjXWsrLZYOPn2u9fLNW1v268.png

So you can keep saving public/Y9GvrBuY6RG2thIrvjXWsrLZYOPn2u9fLNW1v268.png in your database but when you are fetching you can do so as follows:

< img src={{"/storage/app/" . $path }} />

//OR

< img src={{ "/storage/../" . $path }} />

This might also be a useful read: https://laravel.com/docs/5.4/filesystem

jontyjago's avatar

Thanks @mushood but the problem is

http://example.com/storage/app/public/Y9GvrBuY6RG2thIrvjXWsrLZYOPn2u9fLNW1v268.png

doesn't work but only

http://example.com/storage/Y9GvrBuY6RG2thIrvjXWsrLZYOPn2u9fLNW1v268.png

does. I have worked round it by using storing the file in public and specifying the file name with storeAs and then storing then file name in the database which allows me to use

< img src={{ "/storage/" . $filename}} />

but that's not ideal for various reasons.

mushood's avatar

@jontyjago ,

In that case,

< img src={{ "/storage/../" . $path }} />

should work.

However, just so I am clear, the ideal situation is to have it stored in the database as "/storage/filename" directly.

then I think @viktorivanov has the correct solution.

HOWEVER, thinking of your way, when you say the following:

$path = $request->file('docfile')->store('public');

you are telling the file to save it to the correct path, then not make that path visible, then save that not visible path to your database and reference the not visible path. For me that seems impossible, without manipulating the $path variable to make it correct.

From documentation, the correct way is to do the following:

By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public

However, you made a symbolic link from public/storage to /storage

jontyjago's avatar
jontyjago
OP
Best Answer
Level 2

Aha! I've cracked it!

My config/filesystems.php was set to

'default' => env('FILESYSTEM_DRIVER', 'local'),

and 'local' is set to 'root' => storage_path('app'),

So by changing the default to 'public' which is set to 'app/public' the files are now saved to the right place.

Thanks for you help!

2 likes

Please or to participate in this conversation.