All about Uploading Files in Symfony


Thumbnailing with LiipImagineBundle

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Go back to the homepage. We're rendering these images with a width and height of 100. But the image behind this is way bigger! That's wasteful: we don't want the user to wait to download these gigantic images, just to see the tiny thumbnail.

Hello LiipImagineBundle

Google for LiipImagineBundle and find its GitHub page. They have a bunch of docs right here... but most of the information actually lives over on Click "Download the Bundle" to get there... and then I'll go back to the homepage - lots of good stuff here.

Start back on the Installation page. Copy the composer require line, find your terminal, paste and... go go go!

composer require liip/imagine-bundle

While we're waiting, head back over to the docs. Thanks to Flex, we don't need to enable the bundle or register the routes - that's automatic. Go back to the homepage of the docs... and click the "Filter Sets" link.

This bundle is pretty sweet. You start by creating something called a "filter set" and giving it a name - like my_thumb or whatever you want. Next, you tell the bundle which filters, or transformations, to apply when you use the my_thumb filter set. And there are a ton of them: you can change the size with the thumbnail filter, add a background, add border color, replace the image entirely with a cat gif - pretty much anything you can dream of. We'll just use the thumbnail transformation, but seriously - check out the full list.

Configuring the Filter Set

Let's go check on the install. Excellent! It's done. And the message is right on: it says we need to get to work in the new config file: liip_imagine.yaml. Go open that: config/packages/liip_imagine.yaml. Uncomment the root key to activate the bundle, leave the driver alone - it defaults to gd - and uncomment filter_sets.

# # valid drivers options include "gd" or "gmagick" or "imagick"
# driver: "gd"
# # define your filter sets under this option
... lines 7 - 42

Let's create our first filter set called squared_thumbnail_small. We'll use this on the homepage to reduce the images down to 100 by 100. To do that, uncomment the filters key and I'll copy the thumbnail example from below, move it up here, and uncomment it.

... lines 2 - 5
... lines 7 - 9
... lines 12 - 42

Set the size to 200 by 200 so it looks good on Retina displays. The mode: outbound is how the thumbnail is applied - you can also use inbound.

... lines 2 - 5
... lines 7 - 9
size: [200, 200]
mode: outbound
allow_upscale: true
... lines 17 - 42

And... I think we're ready to go! Copy the squared_thumbnail_small name and go into homepage.html.twig. To use this, it's so nice: |imagine_filter() and then the name.

... lines 1 - 2
{% block body %}
... lines 4 - 20
{% for article in articles %}
<div class="article-container my-1">
<a href="{{ path('article_show', {slug: article.slug}) }}">
<img class="article-img" src="{{ uploaded_asset(article.imagePath)|imagine_filter('squared_thumbnail_small') }}">
... lines 25 - 37
{% endfor %}
... lines 41 - 63
{% endblock %}

The Thumbnailing Process

Let's go try it! Watch the image src closely. Refresh! It includes the part, but that's not important. The path - /media/cache/resolve/squared_thumbnail_small/... blah, blah blah - looks like a path to a physical file, but it's not! This is actually a Symfony route and it's handled by a Symfony controller!

Check it out: at your terminal, run:

php bin/console debug:router

There it is! The first time we refresh, LiipImagineBundle generates this URL. When our browser tries to download the image, it's handle by a controller from the bundle. That controller opens the original image, applies all the filters - just a thumbnail in our case - and returns the transformed image. That's a slow operation: our browser has to wait for all of that to finish.

But, watch what happens when we refresh. Did you see it? The path changed! It was /media/cache/resolve - but the resolve part is now gone! This time, the image is not handled by a Symfony route. Look at your public/ directory: there is now a media/ directory with cache/squared_thumbnail_small/uploads/article_image/astronaut-...jpeg.

The full process looks like this. The first time we refreshed, LiipImagineBundle noticed that no thumbnail file existed yet. So, it created the URL that pointed to the Symfony route & controller. The page finished rendering, and our browser make a second request to that URL to load the image. That request was handled by the controller from the bundle which thumbnailed the image, saved it to the filesystem, and returned it to the user. That's slow.

But when we reloaded the page the second time, LiipImagineBundle noticed that the filename already existed and generated a URL directly to that real file. The request for that image was super fast.

Oh, also check out the .gitignore file. Thanks to the Flex recipe, we're already ignoring the public/media directory: we do not want to commit this stuff: it'll just regenerate if it's missing.

So, yea - it all kinda works perfectly!

Next, let's add another filter set for the show page and add an image preview to the article form.

Leave a comment!

  • 2019-04-04 ali nizar

    We are still waiting for the continuation of the course

  • 2019-03-25 weaverryan

    Hey Cryptoblob!

    Sorry for the slow reply. Hmm. So the key thing is this: when you open the broken image URL in a new browser and get the "404" error... what *exactly* does that error look like? Is it a Symfony 404 error with a big stacktrace (it should be) or is it just a generic 404 error from your web server. Also, does that broken URL have the word "resolve" in it or not (it should)?

    As you can see, there are a number of different possible ways things could be going wrong. Your web server could be intercepting these requests (thinking they are actual files), which should be processed by a Symfony controller so that the image can be created. Or, Symfony could be handling it, and something is going wrong. The fact it seems to work... then not work.. is a mystery. But we can start with these questions to dig in.


  • 2019-03-21 Diego Aguiar

    Hey Peter Kosak Have you checked out this chapter?
    It's about handling absolute paths, I think you will be able to fix your problem after watching it, if that's not the case I may have to see your code (specially the part where you generate those paths) :)

  • 2019-03-21 Victor Bocharsky

    Hey Krzysztof,

    Are you talking about .htaccess in public/ directory? I suppose you use Apache web server, did you set up the public/ directory as your document root in Apache config? Do you have any symlinks in the actual path of your document root?

    It would be good if you could debug things a bit, what is the generated link to your thumb in the HTML? What is your actual path to the image in the file system? Can you find the thumbs in the file system?


  • 2019-03-21 Peter Kosak

    did some digging and it looks like the URL is wrong:



    but see that cb/public should not be there on live but because my root folder is cb/public thats why symfony somehow use it... I need to set somewhere in liip a root to be cb/public?

    When I remove second "cb/public" from url thumbnail will be generated

  • 2019-03-20 Peter Kosak

    sorry when I said on production I meant on godaddy live server,, it is working on localhost when environment is set to prod or dev but when deploying on live server (prod or dev environment) and refresh the page it wont create thumbnails

    this is an error on live server when setting env to dev

    Source image for path "cb/public/images/gallery/7d5701d922354c0d5267137297bf63cc.jpeg" could not be found

    when I set it to prod I obviously get 404 page so the issue is somewhere with the php settings but not sure where on godaddy as my gd is enabled memory is fine chmod is fine as well so I am not sure why is that file not created on live server

  • 2019-03-20 Diego Aguiar

    Hey Peter Kosak

    So it's working on dev but not on prod? This may sound silly but did you clear prod's cache? Are you overriding any configuration for prod environment?

  • 2019-03-19 Peter Kosak

    issue was memory limit - when increased it is working on development however when tested on production it is failing and not a single thumbnail image is created... folder not created, gd extension enabled, manually created folders and set permission to 777 and still nothing.... didnt dig deep but it is annoying to have these issues

  • 2019-03-19 Krzysztof Krakowiak

    I am running server through PHP Storm (PHP Build-in Server)

  • 2019-03-19 Krzysztof Krakowiak

    Hmm I am getting 404 for these thumbs. There was no folder created anywhere (suppose to?)

    Partially RESOLVED FOR DEV: I had to run server through bin/console server start

    Anyway On production I wont be able to do that, and seems that problem refers to Apache configuration, these requests do not go through index.php and return 404, not sure what I should change to avoid that

    it might refer to these lines in my .htaccess:
    # If the requested filename exists, simply serve it.
    # We only want to let Apache serve files and not directories.
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ - [L]

    But it is stated that only if file exists, in this case file do not exists and this request should be processed by index.php, I am not sure why this do not work.

  • 2019-03-18 Cryptoblob

    Hi weaverryan sorry I probably should have been clearer.

    I'm getting a 404 error for all of my images, if I open the images in a new tab I still cant see it. When i change the config it just completely breaks and all the images break, its as if the media/cache isnt clearing or something. My images are stored in the public/images folder.

    If i was to change the 'thumbnail' to size [300,300] or anything else, it'll break. Just says 404 the file doesnt exist.


  • 2019-03-18 weaverryan

    Hey Cryptoblob!

    We can definitely help :). Can you describe what you mean by things "not working"? Are the thumbnails simply showing up as broken images? If you go directly to the thumbnail image src that's broken in a new browser tab, do you see the image? Or an error? What does your Twig code look like and where are the original images stored?


  • 2019-03-16 Cryptoblob

    Im working on a different project and my filters just weren't working at all. So i deleted the media folder now everything is broken... how do i get the media folder back?

    EDIT: Nevermind i fixed it, i was using imagick instead of gd, i dont have imagick installed. Funnily enough my filters are also working now.

    Edit again.. : Not working again... can someone help please? here is my config

    # valid drivers options include "gd" or "gmagick" or "imagick"
    driver: "gd"

    # define your filter sets under this option

    # an example thumbnail transformation definition

    # set your image quality defaults
    jpeg_quality: 90

    # setup the filter steps to apply for this transformation

    # auto rotate the image using EXIF metadata
    #auto_rotate: ~

    # strip the image of all metadata
    strip: ~

    # scale and square the image to the given dimensions
    size: [341, 341]
    mode: outbound
    allow_upscale: false

    # # create border by placing image on larger black background
    # background:
    # size: [341, 341]
    # position: center
    # color: '#000'

  • 2019-03-11 weaverryan

    Hey Peter Kosak!

    Ok, woh, something weird is happening. Here's what we should test:

    Reset things and refresh the page so that you can see the missing thumbnail. Right click and get that image src= value. Open that directly in a new tab in your browser? Do you see the image? An error? Is the thumbnail created?

    When your browser makes the request for the image, that is handled by a Symfony controller that is responsible for creating the thumbnail, saving it, and returning it to you (actually, if it's successful, it will redirect you to the final location - you'll see the URL change - it will no longer contain the word "resolve" after it's redirected). So, if something is not working - I'd go directly to that URL in your browser so you can (maybe) see what's going on.

    Let us know what you find out!


  • 2019-03-09 Peter Kosak

    I have tried to refresh, go back, etc and it would not recreate thumbnails for new upload and first image then I went to symfony profiler and hit back and it was working... I have tried to delete whole media folder and refresh... again first picture not working, again tried refresh clear cache refresh go to other page and back to gallery still nothing....went to profiler and back and suddenly it has recreated a thumbnail

  • 2019-03-09 Peter Kosak

    another issue I have is when I add another image to gallery it wont create thumbnail... I thought that as soon as there is not a picture in media it will try to create a thumbnail. Am i being stupid or thats not what should happen?

  • 2019-03-09 Peter Kosak

    Well I have an issue, I have a gallery and first picture in the loop is never done. Only the first picture. I have tried to delete that picture from the loop (database) and again first picture is not done. I have tested this with thumbnail filter but also watermark. Same issue on both filters.

  • 2019-03-06 Diego Aguiar

    Yeeeah, LiipImagineBundle FTW!

  • 2019-03-06 Peter Kosak

    wau I would have never though it is working this way.... I was always thinking that during upload you need to upload big picture and also make a thumbnail so the logic would be sitting somewhere in upload service class...this is actually superb *thumbs up*