27

I upload all user files to directory:

/resources/app/uploads/

I try to get image by full path:

http://localhost/resources/app/uploads/e00bdaa62492a320b78b203e2980169c.jpg

But I get error:

NotFoundHttpException in RouteCollection.php line 161:

How can I get image by this path?

Now I try to uplaod file in directory /public/uploads/ in the root:

$destinationPath = public_path(sprintf("\\uploads\\%s\\", str_random(8)));
$uploaded = Storage::put($destinationPath. $fileName, file_get_contents($file->getRealPath()));

It gives me error:

Impossible to create the root directory 
7
  • try uploading in public folder.. then you should be able to access with asset() method.. Commented Aug 3, 2016 at 7:15
  • Okay, how to specify path to public directory in Storage::put()? Commented Aug 3, 2016 at 7:19
  • you can use public_path() when saving and asset() when retrieving.. Commented Aug 3, 2016 at 7:23
  • You mean that: Storage::put(public_path().'/'.$file)? Commented Aug 3, 2016 at 7:24
  • can you post your code snippet? Commented Aug 3, 2016 at 7:41

7 Answers 7

41

You can make a route specifically for displaying images.

For example:

Route::get('/resources/app/uploads/{filename}', function($filename){
    $path = resource_path() . '/app/uploads/' . $filename;

    if(!File::exists($path)) {
        return response()->json(['message' => 'Image not found.'], 404);
    }

    $file = File::get($path);
    $type = File::mimeType($path);

    $response = Response::make($file, 200);
    $response->header("Content-Type", $type);

    return $response;
});

So now you can go to localhost/resources/app/uploads/filename.png and it should display the image.

Sign up to request clarification or add additional context in comments.

2 Comments

Logic should not be placed in the path, it belongs in the controller or the model.
I tried this approach using Laravel 8 (ex: localhost:8000/files-layout-test/…) and I get Not Found message. But when I take away the file name extension (ex: localhost:8000/files-layout-test/backend-layout-header-tb02-03), goes through, but I need the file extension to be there. Any ideas on why this could be happening?
31

You may try this on your blade file. The images folder is located at the public folder

<img src="{{URL::asset('/images/image_name.png')}}" />

For later versions of Laravel (5.7 above):

<img src = "{{ asset('/images/image_name.png') }}" />

5 Comments

In Laravel 5.7 you an just do {{ asset('/images/image_name.png') }}
@Sl4rtib4rtf4st, yes. will edit my answer to reflect the said alternative on Laravel 5.7
And also, you may define the asset path by setting ASSET_URL in .env file.
@Sl4rtib4rtf4st what would be the folder path for such assets? Do I store it in resources?
@abhig10 still in the public folder
10

Try {{asset('path/to/your/image.jpg')}} if you want to call it from your blade

or

$url = asset('path/to/your/image.jpg'); if you want it in your controller.

Hope it helps =)

Comments

9

As @alfonz mentioned, resource_path() is correct way to get the resource folder directory. To get a specific file location, code will be like the following

 $path = resource_path() . '/folder1/folder2/filename.extension';

Comments

1

First, change your config/filesystems.php

'links' => [
        public_path('storage') => storage_path('app/public'),
        public_path('resources') => resource_path('images'),
    ],

Then normally run

 asset('resources/image.png')

you will get the file URL.

Comments

0

Laravel 10 Asset Bundling (Vite)

if you want to process and version all images stored in resources/images you should add the following in your application's entry point resources/js/app.js

import.meta.glob([
  '../images/**',
]);

After then reference these assets in blade like that

<img src="{{ Vite::asset('resources/images/logo.png') }}">

to get it work, need to build npm run build or run Vite development server npm run dev

For more information https://laravel.com/docs/10.x/vite#blade-processing-static-assets

Comments

0

I would recommend to move the files to the public folder. There are 2 measures I would like to describe to enhance the security here.

  1. Hash the name to avoid/difficult Path Traversal like attacks. So, instead of serial file names like 01.jpg, 02.jpg, something like i3u4b23iu23jib2k3jb4.jpg will be used instead.
  2. If some files must be protected from direct access from the users, store these files on something like public/protected_files/your_file_name.jpg. Then, on Laravel's routes/web.php file, create a route entry where the url path to the protected_files is inside some checkAdmin middleware, allowing only registered as admin users to have access:
Route::middleware('auth')->group(function ()
{
    // Routes accessible only for authenticated admins
    Route::group(['middleware' => 'admin'], function () {
        Route::get('/protected_files/{filepath}');
    });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.