kareemshahhat0's avatar

Hello guys I have a problem linking images in Laravel 10 controller

When I save the images in the path, they are saved as required, which is this path: project\storage\app\public\images.

In the index controller, I return to the blade table 'ajax yajura' with the product data. When I call these images in the controller, it takes me to this path: project\public\storage\images.

I've tried everything and it didn't work for me. my controller code

class SparePartController extends Controller { /** * Display a listing of the resource. */ use UploadImage ;

const imgPath= 'public/images/spare_parts/'; // img save path

public function index(Request $request)
{
    if ($request->ajax()) {
        $data = spare_part::select('*');
        return Datatables::of($data)
            ->addIndexColumn()
            ->addColumn('img', function ($device) {
                $imgUrl = Storage::url('public/images/spare_parts/' . $device->img); // <-- here the problem

                // Check if the image exists
                if ($device->img != 'no img') {
                    return '<img src="' . $imgUrl . '" alt="img error" style="max-width:70px">';
                } else {
                    return 'no img';
                }
            })
            ->rawColumns(['action','status','img','created_at'])
            ->make(true);

    }
    $spare_part = spare_part::all();
    return view('dashboard.spare_parts.index',compact('spare_part'));
}

  public function store(Request $request)
{
    $validated = $request->validate([

        'img'=>'nullable|image|mimes:jpeg,png,jpg|max:2048',
  
    ]);

    $req =  $validated;

    if ($request->file('img')){

        $fileName = $this->uploadIm2(request(),'img','public/images/spare_parts/' );
        $req['img'] = $fileName;
    }else{
        $fileName='no img';
        $req['img'] = $fileName;
    }

    spare_part::create($req);

    return redirect()->route('dashboard.spare_parts')->with('success', 'تم الاضافه بنجاح');
}

and here uploadIm2 function if you need

function uploadIm2(Request $request, string $requestKey, string $path): string {

    // Get the uploaded image
    $image = $request->file($requestKey);

    // Generate a unique filename with extension
    $filename = uniqid('', true) . '.' . $image->getClientOriginalExtension();

    // Store the image in the path
    $image->storePubliclyAs($path, $filename);

    // Return the image name
    return $filename;
}

I try this

php artisan storage:link

and try all this in controller

$imgUrl = asset('./storage/images/spare_parts/' . $device->img); $imgUrl = Storage::url('images/spare_parts/' . $device->img); $imgUrl = Storage::disk('public')->url('images/spare_parts/' . $device->img); $imgUrl = storage_path('public/images/spare_parts/' . $device->img); and

Also, the problem hasn't been resolved. It's calling the images from a different path, which is this path: project\public\storage\images. Even when I try to save the images in this path, it doesn't accept.

0 likes
15 replies
Snapey's avatar

you have not said what is wrong?

2 likes
kareemshahhat0's avatar

@Snapey

The problem is that when I call the images from the storage path, it goes to the wrong path. Here is the correct path:

MyProject\storage\app\public\images

Instead of:

MyProject\public\storage\images

Here is the code snippet where the issue lies:

$imgUrl = asset('storage/images/products/' . $device->img); return '';

1 like
amitsolanki24_'s avatar

@kareemshahhat0 Whenever we use asset() it is adding public folder path as a prefix.

That's why we use stoarge:link command to create link of storage folder inside public folder.

dkroft's avatar

When you save an image to your filesystem, you can find it (on your filesystem) using a file path (because you are working in the context of your local filesystem).

When a web request attempts to load that same image, it must access it differently using a web URL https://.. that your web server must resolve like every other web request:

  • through your ./public directory using your apache or nginx configurations.
  • Laravel creates a couple of soft links under ./public to make some "local" directories appear to be "public" (a filesystem "softlink" is like a shortcut inside a directory that points to a file or directory that is really somewhere else).
  • Laravel also provides a couple of helper methods to simplify getting the correct "path* to a file when you want a browser to load it (URL), or when you want your code to load(or save) it. Whenever Laravel "magic" feels confusing, try using an IDE (code editor like VS Code or PhpStorm) to push down through methods to see what they are actually doing.
1 like
kareemshahhat0's avatar
kareemshahhat0
OP
Best Answer
Level 1

Thank you all for the help, but the problem was somewhat strange and not repeated. After trying many times, I found that solving the problem is as follows: In config/filesystems.php: 'disks' => [

'local' => [
    'driver' => 'local',
    'root' =>  public_path(),    //The change has been made from storage_path('app') to public_path()
    'throw' => false,
],
gych's avatar

@kareemshahhat0 When storing an image that needs to be publicly accessable you should use the public disk instead of local disk.

By setting the local disk root to public path, files will be saved in your project's public folder and not in storage/app. Revert this change and use a better solution to fix the problem.

When storing the image in your db don't add `public' to the path, use: 'images/spare_parts/' . $device->img without public

Store the files in the public storage disk and make sure you have symlink between the storage public folder and your application's public folder php artisan storage:link

1 like
kareemshahhat0's avatar

@gych I used to work with this method and tried this solution, and I'm sure everything is connected properly: images/spare_parts/' . $device->img without public. But it didn't work for me. This is the only method that made the images appear in the blade

gych's avatar

@kareemshahhat0 Then something still wasn't set right. Did you try without Storage::url() because that's not necessary when using the public disk, only with the local disk.

kareemshahhat0's avatar

@gych yes i have tried all of thise

$imgUrl = './storage/images/spare_parts/' . $device->img;

$imgUrl = asset('./storage/images/spare_parts/' . $device->img);

$imgUrl = Storage::url('images/spare_parts/' . $device->img);

$imgUrl = Storage::disk('public')->url('images/spare_parts/' . $device->img);

$imgUrl = storage_path('public/images/spare_parts/' . $device->img);

and still doesn't work

Snapey's avatar

@kareemshahhat0

what exactly does $device->image contain?

where in your file system is the file stored?

what are you config disks? (inside config/filesystem.php)?

What is the url of the page with the table?

When you provide 4 answers, Ill tell you exactly what to do

gych's avatar

@kareemshahhat0 If the file is stored in the public disk and you have storage symlink with the public folder you can just use $imgUrl = '/storage/images/spare_parts/' . $device->img; as img src

Snapey's avatar

@gych not quite, the symlink always goes to /storage/ something

1 like
gych's avatar

@Snapey Yes indeed, I've corrected the img path in my previous reply

Please or to participate in this conversation.