Reputation: 889
Im currently storing images via file input like so:
<input type="file" name="images" class="form-control">
Inside the store function, i store the file & the url like so:
$blog = new Blog;
$path = Storage::putFile('image', $request->file('images'));
$url = Storage::url($path);
$blog->file = $url;
$blog->save();
Whichs works just fine. As a path in tinker i get for the file string for each blog ($blog->file) the following response:
"/storage/images/GmjAKA6FkId7vli2aw1oq2Z3MkAzZQRxGPoQeVud.jpeg"
To display an image on the view part, i use:
<img src="asset/{{ $blog->file}}" alt="" class="card-img-top">
which prints out:
<img src="asset/storage/images/GmjAKA6FkId7vli2aw1oq2Z3MkAzZQRxGPoQeVud.jpeg" alt="" class="card-img-top">
in the console.
Inside storage/images i can also see all images that been uploaded. However, in my text editor there is an "app" folder in between storage and images like so:
"storage/app/images"
which is the reason no image gets displayed.
Since i'm using Storage.put, why is Storage saving the path as "storage/images/" instead of "storage/app/images"?
Filesystems.php:
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
];
i ran php artisan link:storage
before (stated in the documentation).
If anyone has an idea what causes this, i'll be glad to hear it!
Thanks in advance everyone!
Upvotes: 1
Views: 6072
Reputation: 21
If anyone is looking for a solution to this, here is a good tip: use laravel-medialibrary.
Medialibrary is a Laravel (5.6 and up) package that can associate all sorts of files with Eloquent models. It provides a simple, fluent API to work with.
Using the example above, you could simply do something like the following:
$blog = Blog::find(1);
$blog->addMedia($pathToFile)->toMediaCollection('images');
Or, if you want to directly handle your uploads, like the case in the problem:
$blog->addMediaFromRequest('image')->toMediaCollection('images');
To retrieve files you can use the getMedia
-method. The method returns a collection of Media
-objects, in other words, it return all media for the given Model:
$mediaItems = $blog->getMedia();
You can retrieve the url and path to the file associated with the Media
-object using getUrl
and getPath
:
$publicUrl = $mediaItems[0]->getUrl();
$publicFullUrl = $mediaItems[0]->getFullUrl(); //url including domain
$fullPathOnDisk = $mediaItems[0]->getPath();
In resume, by using this library you don't need to worry about any storage configuration directly, you can do everything by calling methods on the model itself. I strongly suggest you to take a look at the Docs, it's really easy to use.
Upvotes: 2
Reputation: 889
Thanks everyone for responding!
I've came up with the following 'solution':
I just store in the public folder, via:
$path = Storage::putFile('public', $request->file('images'));
It seems that storage:link can only expose the public folder.
Upvotes: 0
Reputation: 11
It's not a good practice to expose your Storage Directory,
//save with
Storage::disk('local')->put('/dir_name/'.unique_file_name.extension, File::get(tmp_dir_received));
it globally references your storage/app directory
to retrieve file content from storage/app/dir_name.
<img src="{{ url('/dir_name/'.$blog->file) }}" alt="" class="card-img-top">
Upvotes: 0
Reputation: 149
It's not php artisan link:storage
but php artisan storage:link
.
You have to you use the asset() helper to get the right path to your image in storage :
<img src="{{ asset($blog->file) }}" alt="" class="card-img-top">
Upvotes: 1