That kind of detail isn’t likely to be in formal documentation, so the best thing to do is just look directly at the source code.
Here it is with the irrelevant parts removed:
function the_post_thumbnail( $size="post-thumbnail", $attr="" ) {
echo get_the_post_thumbnail( null, $size, $attr );
}
/**
* Retrieve the post thumbnail.
* @return string The post thumbnail image tag.
*/
function get_the_post_thumbnail( $post = null, $size="post-thumbnail", $attr="" ) {
if ( ! $post ) {
return '';
}
$post_thumbnail_id = get_post_thumbnail_id( $post );
if ( $post_thumbnail_id ) {
//...
} else {
$html="";
}
/**
* Filters the post thumbnail HTML.
* @param string $html The post thumbnail HTML.
*/
return apply_filters( 'post_thumbnail_html', $html, $post->ID, $post_thumbnail_id, $size, $attr );
}
So, you can see that the_post_thumbnail()
just echos whatever is returned by get_the_post_thumbnail()
. The docblock for get_the_post_thumbnail()
declares that it returns a string, and that matches the code.
So, if a featured image isn’t set, it should just return an empty string, which will then be echo’d, which will have no effect on the rendered markup.
If another plugin filters the output of post_thumbnail_html
, then it could return something else, of course, even if a thumbnail isn’t set.
So, in your specific case, wrapping the call in has_post_thumbnail()
would just be a precaution against unintended side-effects, but it doesn’t seem likely that you’ll run into any problems if you leave it out.
In you wanted to add extra markup around the image, though, then it would be necessary (props @swisspidy). e.g.:
<?php if ( has_post_thumbnail() ) : ?>
<header class="entry-header">
<?php the_post_thumbnail(); ?>
<p>Lorum ipsum blah blah blah</p>
</header>
<?php endif; ?>