I am having a problem using the filesystem in Laravel 5.3. I am trying to save a file to my local storage but when I call either $file->store('directory', 'local') or Storage::putFile('directory', $file) it stores in the correct location storage/app/directory/filename but the path returned by both functions does not include the path to the storage/app directory, just directory/filename.
My local storage driver config is as below:
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
Obviously I could wrap the $path with the storage_path() helper but this doesn't seem right when reading the docs.
https://laravel.com/docs/5.3/filesystem#storing-files
Am I doing wrong or missing something?
it's not actually crazy. The storage path is configurable, therefore if Laravel were to store it in database but you changed it down the line, there would be an issue.
What you can do simply is add storage_path($file) when you try to display your file in your blade template. That will automatically apply the proper path to storage before the file name and should find your file where it is.
Tell me if that helped/worked
This is by design because in your config, you've already set the storage/app directory as your root directory.
So, it returns the path relative to your root.
Take the case that you want it to return absolute rather than relative paths. Now imagine if your Storage driver was an AWS S3 bucket. In this case there is no absolute path. The absolute path is a term specific to the local driver but the code was written to be extended/used by multiple drivers (and hence they wanted a consistent return value for the putfile method). So, relative path was the only choice in this case
Related
hope you are doing really good today, I'm trying to copy a file using the function copy from Laravel Storage, but I don't know where it is saving them cause the first time looks normal but after the second shot I got an error about the file already exists, but I don't know where is saving it, this is my code, $dirDest should be a folder inside of my project but is not saving it there and I've already searched it in the ftp directory, hope you can help me.
$dirDest = 'temp-docs\temp.pdf';
Storage::disk('custom-ftp')->copy($this->document_path, $dirDest);```
Regards!
Check the path you have configured for your 'custom-ftp' in filesystems.php. This part:
'custom-ftp' => [
...
'root' => 'your/base/path',
...
],
You file copy will be located in this root folder + 'temp-docs\temp.pdf'
The copy function does not changes the driver. So it copies just inside of your ftp server.
To copy the file from one server to another (or your server) use a combination of get and put functions from the storage drivers.
$file = Storage::disk('my_ftp')->get($this->document_path);
Storage::disk('other_ftp')->put('temp-docs\temp.pdf', $file);
After that you will find the file of the other server root folder + 'temp-docs\temp.pdf'
I would also recommend you use the exists function to be sure that the file is there before you copy it.
Storage::disk('my_ftp')->exists($this->document_path)
I started writing an app for nextcloud. For my app to work, I need to be able to pass the complete path of files located in the file directory of the logged in user to a CLI command.
I know that the base path of the file directory is defined in config.php; for example, it is 'var/www/html/nextcloud' or 'var/www/nextcloud'.
I have found a couple of functions that allow me to get the relative path, e.g.
\OC\Files\Filesystem::getFileInfo($path)
and
\OC\Files\Filesystem::getInternalPath($path)
Unfortunately, I couldn't find a function that either directly returns the full path of a file or at least the base path from config.php.
Do any of you have a tip for me?
Thanks for your help, misorude!
In the meantime I have found a solution:
in Nextcloud there is a class \OC\Config which has the method OC\Config::getValue($key, $default=null)
(see https://docs.nextcloud.com/server/latest/developer_manual/api/OC/Config.html)
The difficulty I had with this was that the initialization of a class instance expects the specification of a path, namely the path where the config.php file is located.
This irritated me at first, because it seems you are chasing your own tail here.
Then I tried specifying only the relative path to the Nextcloud installation, and that worked immediately. So to make it short, here's the code you need:
$config = new \OC\Config('config/');
$base_path = $config->getValue('datadirectory')
datadirectory is the key in the array defined in config.php that contains the base directory.
$basepath now contains a path like /var/www/html/nextcloud/data.
I hope this helps someone.
Best regards,
Tom
In my laravel project, I have a form for uploading a file and removing it.
I create a disk in config/filesystem:
'upload' => [
'driver' => 'local',
'root' => public_path(),
'url' => env('APP_URL'),
'visibility' => 'public',
],
Here uploading file work correctly but when I want remove them from public folder the file not exist:
$img_path = public_path( $this->directory . '/' . $this->getFliename());
$img_path = str_replace( "/",'\\', $img_path); // checked with it & without it
// $img_path= "C:\Users\Me\Desktop\final\public\upload\users\1\5bc722d2b7c05.jpg"
dump(File::exists($img_path)); // it always return false
// and then which one
File::delete($img_path);
Storage::disk('upload')->delete($img_path);
why this file doesn't exist, and which one for deleting a file is true?
It becomes more complicating when I do it with route???
// testing ...
Route::get('/test', function (){
File::delete('C:\Users\Me\Desktop\final\public\upload\users\1\5bc722d2b7c05.jpg');
});
The file might exist on the filesystem, but the web user that PHP is running under might not have permission to read, update, or delete the file.
On a linux or mac system, you'll typically want to give the web user ownership of the file, and set file permissions to 664 and folder permissions to 775.
644 and 755 should also work and give you slightly stricter permissions.
If the above fails, try 777 just to debug, but do not do that on production as it's a serious security issue.
I'm not sure how it is done on Windows, but hopefully this gets you on the right path.
As you are storing images in public/upload folder :
$user_id= $user->id;
$file_name=$user->image;
$img_path=public_path('upload/users/'.$user_id. '/' .$filename);
if(is_file($img_path)){
unlink($img_path);
// or File::delete($img_path);
}else{
echo "File does not exist";
}
Your $img_path appears to be set with the full path to the file, rather than a path relative to the base of your specified disk that would have been returned by $file->storeAs() when you saved the file.
This should work:
Storage::disk('upload')->delete('upload/users/1/5bc722d2b7c05.jpg')
If you need the full path on disk for some reason, try this:
Storage::disk('upload')->path('upload/users/1/5bc722d2b7c05.jpg')
Check if the file exists:
Storage::disk('upload)->exists('upload/users/1/5bc722d2b7c05.jpg')
OR File::exists(Storage::disk('upload')->path('upload/users/1/5bc722d2b7c05.jpg'))
(returns C:\Users\Me\Desktop\final\public\upload/users/1/5bc722d2b7c05.jpg because your 'upload' disk has a base of public_path())
Read/write permissions for the web server could also come into play, depending on your server configuration. Typically you would not store things directly in the public/ folder, but rather in storage/app/public and use php artisan storage:link to generate a symbolic link to the storage directory. You can read more here: https://laravel.com/docs/5.7/filesystem#the-public-disk
As a side note, Windows accepts either / or \, so using / makes your scripts much easier to use on other systems and reduces headaches in string escaping.
I have a .json file that I want to define on .env.
How do I do that ?
my json file is on (laravel root folder)/json_google/api_key.json .
I tried GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=/json_google/api_key.json but doesn't work ..
Laravel has many helper functions to resolve the path. Such as base_path() in your case. You'll find all helpers here: vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
base_path(env('GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION');
However, I'd set the full path instead of a relative path. Otherwise your application has to know what it should be relative to (laravel root, or app path, ...) and take this into account, which kind of defeats the purpose of putting the file location outside your code base, as it makes it harder to move it to some place else.
As the .env file is per deployment, there is no problem with setting the full path.
You should use .env variable using constants file.
.env file
GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=/json_google/api_key.json
Now in config/constatns.php set
return [
'STORAGE_GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION' => env("GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION", ""),
];
Fetch json file path
Config::get('constants.STORAGE_GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION')
I've been using laravel for nearly all my projects and I've came across a problem when trying to list all files in a directory.
Here is my code below:
$directory = ("upload/"."$username->username");
$scanned_directory = storage::allfiles($directory);
So as you can see First line is the directory which is in Upload followed by the username of the account.
The second line is meant to scan this directory and list only files. Sadly it always gives me back an empty array. Using Scandir() here works... But it gives me folders which I'm not wanting.
So... Any tips? I checked the API and I really can't see what is wrong here :(
The reason you're getting no results when using the Storage::allFiles('directory') method is this method only looks inside of your application's storage folder, usually storage/app. Hence why modifying the storage path in configuration works as mentioned by #yassine (you shouldn't do this).
If you wish to use files outside of the storage folder, simply use the File facade instead. e.g. File::allFiles('directory')
Me too i had the same issue for local storage. I fixed it by :
project/config/filesystems.php
line 44
changed root folder to from storage_path('app') to changed to
base_path()
then I provided a related path to the root folder in Storage::files() or Storage::allfiles().
Like Storage::allfiles("app") if I want to fetch files withing the sub folder "app" relative to the base path given in the config file.
Good luck
$direcotry has to be an absolute path from your laravel root folder.
When your uploaded folder is in the root folder try this
$directory = base_path("upload/"."$username->username");
$scanned_directory = storage::allfiles($directory);