I’ve spent another week working on programming custom WordPress themes, and I’d like to share a fix for the “phantom image bug.” I just made that up. It’s not a real WordPress core bug. But it is a real life programming problem that you might encounter, especially if you’re working with migrated content, or for some reason your database has weirdness. (Funky database, eh?)
The typical way to check for whether a WordPress post has a featured image is to use the function has_post_thumbnail() This function calls get_post_thumbnail_id(), which queries the database for the post meta field _thumbnail_id
If the field _thumbnail_id is not empty, has_post_thumbnail() will return true.
has_post_thumbnail() does not actually check to see whether _thumbnail_id is an actual ID of an object that exists in your database. So, on the rare occasion, has_post_thumbnail() will return true when the post thumbnail does not actually exist.
Assuming that you’re in The Loop, you can fix this problem, by replacing:
if ( has_post_thumbnail() ) { // do a bunch of stuff }
with
$featured_image_url = wp_get_attachment_url( get_post_thumbnail_id( get_the_ID() ) ); if ( ! empty( $featured_image_url ) ) { // do a bunch of stuff }
This checks to see if the actual image URL exists. In my particular case, this solved the problem. There’s still the chance that the URL points to a file that doesn’t exist. If that’s the issue, then this fix won’t work, and you have bigger problems. But in that case, you’re probably seeing a broken image icon, rather than just a blank spot.
Fortunate for me, this fixed the issue with has_post_thumbnail coming back erroneously true. Since it was returning true, an empty HTML <DIV></DIV> was being output, which was causing issues with the website’s layout. Actually, in my case, there was also a caption appearing because there was logic written into the template that said to display a custom caption. So it was extra ugly.
Hopefully, I’ve helped someone out here. Probably my future self will enjoy finding this code snippet someday…
Yes, this explanation helped me a lot, thank you very much! This always happens when I have imported a database to a new wordpress dev (developing a new site ) when I don’t have all the images assets. This code snipped should be the correct way for WordPress to check for an existent featured image.
Thanks Linnea this helped a lot. Although I knew it would return TRUE based on a comment in the WordPress Codex, there was no solution. Now there is!
That’s a really straight forward fix, this issue killing me. Thanks for sharing!
I’m adding the phrase ‘false positive on has_post_thumbnail()’ here so others who search that phrase will find you before asking elsewhere like I did on SO. Thank you!
Never seen this before… until today. Found this page, issue resolved in less than 3 minutes.
This was really helpful! WordPress Codex does mention about the function ‘has_post_thumbnail’ returning true even if there is no featured image, but an image uploaded in the post content, but there was no further explanation or solution for the ‘phantom’ bug. Thank you so much for the great help!
You restored my sanity. Thank you!
don’t test if empty, because function return url or false.
So just test
if($featured_image_url) { …}
THANK YOU SO MUCH <3
Hi, somehow its a strange behavior I am facing since a day. when I call has_post_thumbnail() within a loop. It just return true and the strange part is the post do not actually contain any featured_image/post_thumbnail. Also the_post_thumbnail() returned Image. I have no Idea
Boom! So helpful. Thanks… Seems like this should be the default behavior of has_post_thumbnail, right?
I ended up using this:
if ( !empty( get_post_thumbnail_id() ) ) :
the_post_thumbnail( ‘big_square’ );
else :
// do a default
endif;
Thank you for sharing this — found it almost 2 years later via Google. I couldn’t figure out why has_post_thumbnail() wasn’t working for me on some posts. This fixed it. Cheers!
Discovered this today… nice fix!
This just helped me out after an hour of “WTF?!!” Thank you.
Definetly, a great fix for this bug – has_post_thumbnail() = bool(true)
Thank i needed this
Thank you so much for this. Such a super frustrating little not-bug-but-bug!