Code Snippet: How to list all WordPress posts and pages that contain a specific image

I was working on a WordPress site recently and needed to remove some old images from the Media Library. Obviously, I didn’t want to remove any images that were still being used in posts or pages. My first thought was to use the Media Cleaner plugin but that was flagging images for deletion that I knew were being used in image gallery blocks on several pages so I came up with another solution that checks if an image exists in the post or page content or if the image is used as a featured image. I created this function to check if an image url is in use.

Add the following code to your site’s functions.php file.

function get_pages_with_image($image_url) {
    // Get the attachment ID from the image URL
    $attachment_id = attachment_url_to_postid($image_url);
    if (!$attachment_id) {
        return 'No image found with that URL.';
	}
    // Query all pages
    $pages = get_posts(array(
        'post_type'   => 'post',  // Set post type 
        'numberposts' => -1,  // Retrieve all pages
    ));
    $pages_with_image = array();
    foreach ($pages as $page) {
        // Check if the page has a featured image
        if (has_post_thumbnail($page->ID)) {
            $thumbnail_id = get_post_thumbnail_id($page->ID);
            
            // If the thumbnail ID matches the image attachment ID
            if ($thumbnail_id == $attachment_id) {
                $pages_with_image[] = array(
                    'ID'    => $page->ID,
                    'title' => get_the_title($page->ID),
                    'url'   => get_permalink($page->ID),
                );
            }
        }
        // Check if the image is attached within the page content (e.g., in the post content)
        $content_str = 'wp-image-' . $attachment_id;
        $content = get_post_field('post_content', $page->ID);
        if (strpos($content, $content_str) !== false) {
            $pages_with_image[] = array(
                'ID'    => $page->ID,
                'title' => get_the_title($page->ID),
                'url'   => get_permalink($page->ID),
            );
        }
    }
    // Return the pages that have the image attached
    if (count($pages_with_image) > 0) {
        return $pages_with_image;
    } else {
        return 'No pages found with this image.';
    }
}

You can call the function by passing the image url to the function which will return a list of pages that contain the image in question.

In future I might expand this to check for WooCommerce product images and turn the whole thing in to a plugin.