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

ronon's avatar
Level 9

Associate multiple images with one post, best way to achieve it?

I'm developing a Blog like site. But now I run into a problem with the database schema and I don't really know whats the best way to solve this.

A post can have exact two Images, a cover and a thumbnail. After the image is uploaded the original image is saved and then a rezised image, created with intervention image, is created and stored in the database.

Idea 1: My first though was to store both image id's in the post schema as well. But then I had the idea to save the original image as well, in case I need to change the image sizes. Now I have to associate 4 images (cover and original, thumbnail and original) with the post.

Idea 2: So I thought a Polymorphic realtion whould be a good way. Problem: A post can only have the mentioned two image types (and there original counterparts). If an image would be changed, i have be sure that only one of each type is associated with the post. Need to make sure that the "old" one isn't associated with the post anymore.

Idea 3: Store the cover and thumbnail as mentioned in idea 1 but with a reference to the original image (parent_id). I cannot estimate the effort to manage the images this way. Is it even a 'good' way?

The next thing, i want to add a person schema with an image, but I'm thinking of storing the original image in case I need to change the size.

What's the best way to handle the images in this case? Would you do it with one of these ideas or do you have a better one? Or would you just create a pivot tables for image_post and later than for actor_image ?

Schema: posts

  • post_id
  • tilte
  • content
  • cover_id ( Idea 1 )
  • image_id ( Idea 1 )
  • timestamps

images

  • image_id
  • file_id ( Unqiue Id with storage path )
  • file_name
  • imageable_id ( Idea 2 )
  • imageable_type ( Idea 2 )
  • parent_id ( Idea 3 )
  • timestamps
0 likes
7 replies
mikefolsom's avatar

My approach lately has been to save only the original, full size image(s) to the storage directory (or S3, etc.) upon upload. Save that file path on the Post record (i.e. as cover_image_path or thumbnail_image_path). Then use Intervention Image's URL based manipulation to generate and cache ALL other sizes on the fly as necessary.

I have loved having the freedom of not being locked into generating additional sizes upon upload. There is one (or in your case, two) file(s) to worry about, and you can just tweak your filter class and clear the cache if your cover image or thumbnail dimensions ever need to change.

ronon's avatar
Level 9

I thought about it too, but if you have lets say 50 posts per page, each image would make a php call and each time laravel would be executed till the point it displays the image. And that is a huge additional cpu load, or am I wrong?

mikefolsom's avatar

Each image URL has to be processed only one time; after that it is cached by Laravel. If the case exists where you are creating 50 posts at once (or maybe you have just modified your Filter class definition and run artisan cache:clear), simply hit the URL before your users do. All the images will be cached on the server and waiting for them.

ronon's avatar
Level 9

I get your point, but my concerns are the same as described here: https://stackoverflow.com/a/29363930

` I never used laravel, but this is a general issue.

If you let the webserver handle the delivery of the image to the client, the php interpreter will not be started.

If you deliver something via PHP (I assume, because you write something about a cached image), you need the php interpreter. Then you need to execute the script, and all its logic, which is in a scripted language always slower, then in native.

Your best bet is, to save the image on the file system, and link to it, instead of a PHP script.

This means for example:

Somewhere in your Application you have a point, where the original image is created. Now think about, what versions of it you need. Resize, crop, edit it as much you want. Save each version you need in your file system. So you have instead of image.jpg a image-200x200-cropped-with-branding.jpg. At this point, performance shouldn't be so much important (The image will be viewed thousands times, but only one time created).`

So intervention cache would add additional load to the server one each request even if it's already genereated or not.

Snapey's avatar

Why not just store a single image reference and then have configured paths (folders) for each image size?

for instance /thumbnail /original /full

You can then build the path to any image from the single reference and the appropriate path for the context in which you want to display the image.

ronon's avatar
Level 9

Hmm never thought about it, will think about it.

mikefolsom's avatar

@ronon Look at the documentation for Intervention Image's URL-based manipulation referenced above. Say you decide that a "thumbnail" should be 256x256. Write a class that defines that version of the file and create a "thumbs" route (look at the docs), then you can use e.g. (simplified for brevity):

<img src="/images/thumbs/{{ $post->thumbnail_image_name }}">

Intervention will generate the 256x256 thumbnail image and cache it the first time the route is hit (i.e. the first time that image is requested by a browser). The next time that URI is hit (by anyone), Laravel will return the cached image, which is VERY fast and low-overhead compared to the initial hit of processing the image for the first time.

Please or to participate in this conversation.