In my application users can upload files. In my controller I have the following:
//...
$request->file->storeAs('/public/user_files',$fileName);
I don't like how I have to hard code the path /public/user_files, what is the proper way to manage file paths? I could simply create a variable but is there any better ways for maximum maintainability?
From my understanding I have a few options:
Create a variable
Create a new file in config directory that manages the path
Create a disk in filesystem.php and use storeAs with the custom disk
What is the best way to handle paths?
In most cases, you should use filesystem disks as you specified in your last option, it allows a centralized flexibility.
In this case, you may use Laravel helpers such as public_path or storage_path, for example:
$request->file->storeAs(
storage_path('app/public'), $fileName
);
Combined to a symbolic link, it allows flexibility about public assets.
https://laravel.com/docs/7.x/filesystem#the-public-disk
you can use helpper public_path()
$request->file->storeAs( public_path('/user_files') ,$fileName);
doc: https://laravel.com/docs/7.x/helpers#method-public-path
Related
What are the option of the method put of Illuminate\Support\Facades\Storage fro Laravel 6
Storage::put($path, $contents [, $options])
This appears to be a way to pass options to the underlying Filesystem driver, so the options vary from driver to driver.
In general, you won't need this much; the most common use case I can find is for telling the S3 driver to make a file public by passing 'public' or ['visibility' => 'public']. (It's likely you could also pass S3 headers here.)
I use Laravel of 5.7.25 version.
I have a symbolic link from public/storage to /storage/app/public.
I'm storing files in /storage/app/public/place-images directory.
I keep the path of stored file in table files which keeps all stored files. The file path would be public/images/some_hash.jpg.
Now I made a file resource, which is used when I'm getting files from my API. The file path retured from api equals public/images/some_hash.jpg. But instead I need it to be images/some_hash.jpg. However, in the table I prefer to keep real path of the file related to the storage folder. After all, I can keep files in AWS or somewhere else.
As far as I understand storage is the root of my disk. The $file->store() method includes public part of the file path.
I end up doing something like this:
// This is ImageResource file, Image model has File relation. One Image has one File
// TODO: Dirty hack
$path = $this->file->path; // This equals 'public/place-images/hash.jpg'
// Removing 'public' part
$charIndex = strpos($path, '/');
$path = substr($path, $charIndex + 1);
return [
'id' => $this->id,
'original_name' => $this->file->original_name,
url' => asset('storage/' . $path) // now we have /storage/place-images/some_hash.jpg which is correct
];
Is there anyway to avoid this dirty hack? I think I'm missing something obvious
storage is not the root of your disk. You can set the root for a disk in config\filesystems.php.
Default root for the public disk defined in config/filesystems.php is /storage/app/public so just store place-images/hash.jpg without public.
If you want to keep files from different disks in one table just add a field with a disk name to this table.
I want to return the files names of a dir called public/uploads. I used Storage::allFiles and Storage::files, but only return an empty array.
Storage works only for storage directory. If you want to use it, you'll need to create a symbolic link.
Use File facade instead:
File::files(public_path('uploads'));
I have baked a File model and controller with default actions. Now I am trying to add an display function which can be used to show images in controlled manner.
I want to protect images so that display function can check does the user have an permissions to view image (image directory is not in a webroot).
I haven't been able to make it work, but when I started from the scratch I managed to find out that really minimal function did work.
Working function looks like this:
public function display($id) {
$this->response->file(ROOT.DS.'img'.DS.'noimage.jpg');
return $this->response;
}
When I add example:
$test=$this->File->findById($id);
to the starting of the function everything breaks.
--> http://www.example.com/files/display/1
The requested file /var/www/example.com/www/img/image.jpg was not found or not readable
Error: The requested address '/files/display/1' was not found on this server.
I have tried with debug zero, file can be found and is readable, obviously because the function without findById works.
Any ideas?
cakephp 2.4.3
You path is totally wrong.
Did you debug() what ROOT.DS.'img'.DS.'noimage.jpg' actually holds?
I bet all the money of the world that you would probably find the solution yourself if you did
The img folder is most likely in webroot
WWW_ROOT . 'img' . DS . 'noimage.jpg'
Note that paths usually end with a DS so no need to add it again.
So if it really is an image folder in ROOT:
ROOT . 'img' . DS . 'noimage.jpg'
Also note that you can easily check if a path is valid using
file_exists()
If the file has the correct file permissions this should return true.
EDIT:
$this->File->...: File is not a good choice for a model name as it collides with the existing core class in Utility. You need to be a little bit more creative with your model naming scheme.
I have been strugling with this for a long while.
I am using an outer API and I need to pass file's path directly. I cannot modify it.
I looks like: functionmethod(String path);
So i cannot use Resource because I need to pass just path.
Is it possible in SPRING?
Maybe you could use:
(new File("")).getAbsolutePath() that gives you the current path (application).
or (I think this one will fit better for you)
getResource("fileName").getFile()