How to delete the image from the storage in laravel?

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

How to Delete Images from Storage in Laravel: A Practical Guide

Dealing with file management in web applications, especially when handling user-uploaded content like images, is a frequent challenge for developers. When a user updates a post and uploads a new image, simply saving the new file isn't enough; you must properly handle and delete the old files to prevent storage bloat and manage disk space efficiently.

This guide will walk you through the correct, robust way to delete old images from your Laravel storage, addressing the specific scenario you presented where you need to remove a previous image when a post is updated.

The Challenge: Deleting Files During Updates

You are trying to achieve an atomic operation: update the database record and delete the corresponding file on the disk. Your attempt using raw PHP functions like File::delete() often fails because it doesn't correctly interact with Laravel’s abstraction layer for file storage, especially when dealing with configured disks.

Let’s look at why your initial attempts might have failed:

// Attempted deletion in updatePost method
File::delete(public_path('storage/image'.$isExist['image']));

This approach is problematic because it bypasses the Laravel Storage facade, which provides a unified and disk-aware way to manage files. Furthermore, constructing paths manually using public_path() can lead to inconsistencies depending on your application's configuration (especially if you are using the default local disk vs. a configured public disk).

The Laravel Solution: Leveraging the Storage Facade

The most reliable method in Laravel is to use the built-in Storage facade, which abstracts away the underlying filesystem details and allows you to interact with files based on the disk you have defined (e.g., public, s3, local).

To successfully delete an image associated with a post, you need two key pieces of information:

  1. The path/filename stored in the database.
  2. The storage disk where that file resides.

Step 1: Storing Files Correctly

Ensure you are using Laravel's Storage system correctly when saving files. When using the storeAs() method, Laravel handles the placement based on your disk configuration. For public assets, storing them on the 'public' disk is standard practice.

Step 2: Implementing the Deletion Logic

We will refactor your logic to use the Storage facade directly within your controller methods. This ensures that when you delete a file, you are using Laravel's intended mechanism.

Refactoring the Update Method

In your updatePost function, before updating the database with the new path, you should check if an old image exists and delete it.

use Illuminate\Support\Facades\Storage;
use App\Models\Post; // Assuming Post model context

public function updatePost(Request $request)
{
    $data = $request->all();
    $postid = $request['id'];
    $post = Post::findOrFail($postid); // Load the post directly for easier access

    if ($request->hasFile('image')) {
        // 1. Check if an old image exists and delete it first
        if ($post->image) {
            // Assuming 'public' disk is configured for storage directory
            $oldImagePath = $post->image; // This should be the path stored in DB, e.g., 'image/filename.jpg'
            
            // Use Storage facade to delete the file from the 'public' disk
            Storage::disk('public')->delete($oldImagePath);
        }

        // 2. Handle the new file upload and storage
        $file = $request->file('image');
        $fileNameToStoreWithExt = $file->getClientOriginalName();
        $filename = pathinfo($fileNameToStoreWithExt, PATHINFO_FILENAME);
        $extension = $file->getClientOriginalExtension();
        $fileNameToStore = $filename . '_' . time() . '.' . $extension;

        // Store the new file to the 'public' disk
        $path = $file->storeAs('image', $fileNameToStoreWithExt, 'public'); // Explicitly use the disk

        // 3. Update the database with the new path
        $post->update([
            'title' => $data['title'],
            'category' => $data['category'],
            'content' => $data['content'],
            'image' => $path // Store the new relative path
        ]);

        return response()->json(['status' => '200', 'response' => 'successfully updated']);
    } else {
        // Handle case where no new image is uploaded
        $post->update([
            'title' => $data['title'],
            'category' => $data['category'],
            'content' => $data['content']
        ]);
        return response()->json(['status' => '200', 'response' => 'successfully updated']);
    }
}

Refactoring the Separate Delete Function

If you have a separate endpoint for deleting a post entirely, the file deletion should follow the same principle:

public function deletePost($id)
{
    $post = Post::find($id);
    if (!$post) {
        return response()->json(['status' => '500', 'error' => 'post not found']);
    }

    // Delete the associated files before deleting the record
    if ($post->image) {
        Storage::disk('public')->delete($post->image);
    }

    $post->delete();
    return response()->json(['status' => '200', 'response' => 'Post successfully deleted']);
}

Conclusion: Best Practices for File Management

Managing file storage is crucial for application health. By relying on the Laravel Storage Facade and keeping your database synchronized with the file system paths, you ensure that file deletion operations are safe, predictable, and scalable. Always prioritize using built-in framework tools like those found in Laravel rather than raw PHP functions for file manipulation. This approach makes your code cleaner, more maintainable, and significantly reduces the risk of errors when handling large amounts of user-uploaded data.