Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vincent15000's avatar

Store images data in the database

Hello,

Although it's not a good idea in most cases, I need to store the images data in the database rather than in a file.

My idea was to store the file data in a field and the file extension in another field. And sure a polymorphic relationship so that I can retrieve the file for the concerned model.

Any suggestions ?

Thanks for your responses.

V

0 likes
11 replies
LaryAI's avatar
Level 58

Storing images directly in a database is generally not recommended due to performance and scalability concerns. However, if you have a specific requirement to do so, you can store the image data as a BLOB (Binary Large Object) in the database. Here's a step-by-step guide on how to achieve this in a Laravel application:

Step 1: Create the Migration

First, create a migration to add a table for storing images. This table will have fields for the image data and the file extension.

php artisan make:migration create_images_table

Then, update the migration file to include the necessary fields:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateImagesTable extends Migration
{
    public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->binary('data');
            $table->string('extension');
            $table->morphs('imageable'); // For polymorphic relationship
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('images');
    }
}

Run the migration:

php artisan migrate

Step 2: Create the Image Model

Create a model for the Image table:

php artisan make:model Image

Update the Image model to include the polymorphic relationship:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Image extends Model
{
    use HasFactory;

    protected $fillable = ['data', 'extension'];

    public function imageable()
    {
        return $this->morphTo();
    }
}

Step 3: Update the Related Models

Assuming you have a Post model that you want to associate images with, update the Post model to include the polymorphic relationship:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    public function images()
    {
        return $this->morphMany(Image::class, 'imageable');
    }
}

Step 4: Store the Image Data

In your controller, you can handle the image upload and store the image data in the database:

namespace App\Http\Controllers;

use App\Models\Post;
use App\Models\Image;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function store(Request $request)
    {
        $post = Post::create($request->all());

        if ($request->hasFile('image')) {
            $file = $request->file('image');
            $imageData = file_get_contents($file);
            $extension = $file->getClientOriginalExtension();

            $post->images()->create([
                'data' => $imageData,
                'extension' => $extension,
            ]);
        }

        return response()->json($post, 201);
    }
}

Step 5: Retrieve and Display the Image

To retrieve and display the image, you can create a route and controller method to serve the image data:

namespace App\Http\Controllers;

use App\Models\Image;
use Illuminate\Http\Response;

class ImageController extends Controller
{
    public function show($id)
    {
        $image = Image::findOrFail($id);

        return response($image->data, 200)
            ->header('Content-Type', 'image/' . $image->extension);
    }
}

Add a route for the image display:

use App\Http\Controllers\ImageController;

Route::get('/images/{id}', [ImageController::class, 'show']);

Conclusion

This approach allows you to store image data directly in the database and retrieve it as needed. However, keep in mind that this method can lead to performance issues, especially with large images or a high volume of image data. For most applications, storing images on the filesystem or using a cloud storage service is a better approach.

vincent15000's avatar

@Snapey It's not my decision, I would have done another way.

We encountered some difficulty with right inside the docker containers to store the images in a folder, this is probably the trigger of the decision, but there is another reason. The images have to be accessible from several microservices and the owner doesn't want any dependency between the Laravel application and the microservices.

The solution could have been to store the image in a separate folder (notice that the application will never be accessible via the web, it will only be accessible via the intranet) independant from the application. Well ...

So the owner has decided that the images are stored in the database (binary) and thus can be accessed by any microservice directly by querying the database.

Tray2's avatar

This is never a good idea, binary data should never be stored in the database. However you need to store it as a blob, or you can base64 encode it and store it as a clob, and then decode it back to binary format.

2 likes
Snapey's avatar

Its also probably the most expensive storage method.

2 likes
vincent15000's avatar

@Snapey I didn't agree with this decision, but I understand the reasons. And even if it's an expensive storage method, it's probably a nice decision according to the project.

And there won't be more than 15 or 20 images.

1 like
vincent15000's avatar

@jlrdw I just start to know docker a bit to understand how it works ... and it was among the contraints imposed by the owner.

I think that the main reason is to let future clients download a docker package and run it locally on their local network.

1 like

Please or to participate in this conversation.