Get the Attachment ID from an Image URL in WordPress

I recently needed a way to get the ID of a WordPress image attachment, but I only had the image URL to work with. The problem was complicated by the fact that the image URL could be a thumbnail of the original image attachment, i.e. one of the auto-generated post thumbnail image sizes.

There’s no built-in function in WordPress for doing this, and a Google search provided only partial solutions. Some of those functions queried attachment GUIDs, but that method isn’t always reliable. Other solutions didn’t work with thumbnail images. However, by combining several of these partial solutions, I put together this function which works well for my purposes:

function pn_get_attachment_id_from_url( $attachment_url = '' ) {
 
	global $wpdb;
	$attachment_id = false;
 
	// If there is no url, return.
	if ( '' == $attachment_url )
		return;
 
	// Get the upload directory paths
	$upload_dir_paths = wp_upload_dir();
 
	// Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image
	if ( false !== strpos( $attachment_url, $upload_dir_paths['baseurl'] ) ) {
 
		// If this is the URL of an auto-generated thumbnail, get the URL of the original image
		$attachment_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url );
 
		// Remove the upload path base directory from the attachment URL
		$attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
 
		// Finally, run a custom database query to get the attachment ID from the modified attachment URL
		$attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) );
 
	}
 
	return $attachment_id;
}

I post it here in the hopes that it may be useful to other developers who are struggling with this same problem, and also as a reference for myself in the future.

If you see a way that this function can be improved, please comment.

43 thoughts on “Get the Attachment ID from an Image URL in WordPress

  1. This is exactly what I needed. Working in Thesis, I’m writing a function that converts the Thesis Post Image (which is a custom post meta) into the WP Featured image. Thanks for sharing this.

  2. Thanks for the very helpful function.

    One tweak I needed to add was to allow for “basedir” as well as “baseurl” as a possible prefix because I’m doing something where I need to traverse the upload directory for files that need processing, so I’m fetching the attachment ID from the file path rather than the URL.

    • Elliott – Would you mind elaborating on where we would place the strstr($imagevar, ‘-‘, true); piece of code to fix this?

      • That would be:


        // Remove the upload path base directory from the attachment URL
        $attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );

        $attachment_url = strstr( $attachment_url, '-', true );

    • Because from a programmatic approach it cripples some otherwise more useful functions such as wp_get_attachment_image( $attachment_id, $size, $icon, $attr );

      Please correct me if I am wrong for I am new to WordPress programming…

  3. Awesome! Thanks so much for posting this; it’s exactly what I was looking for. I had been using Pippin’s solution (which worked well), but was running into issues with the auto-generated image sizes.
    Thanks again, this really helped me out.

  4. Hi, I have been trying to achieve something similar and your post has helped loads. What I am trying to do is get the attachment id and following attachment page from any image URL. I am using eazyest gallery to ftp my images so they go into a different directory than the upload directory, thus your query did not work to get the attachment id. I modified it as below.


    $attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts WHERE wposts.post_type = 'attachment' AND wposts.post_mime_type = 'image/jpeg' AND INSTR('%s',wposts.post_name)>0", $attachment_url ) );

    Since the post name for an attachment file always seems to be the file name of the original file one can use this to match the URL to the relevant post. This works great and I can get the ID.

    Though I am facing a different problem now. Which I am hoping for some advice on. I want to use the ID to find the attachment page so that I can link to it, the problem is regardless of whether I use
    wp_get_attachment_link( $attachment_page_id, '', true, '', 'attachment link true' );
    or
    wp_get_attachment_link( $attachment_page_id, '', false, '', 'attachment link false');
    the result is the same and links to the image file instead of the attachment page. I know the attachment page exists since I can get to it from the wordpress admin (view attachment page button). I can also use the id to get all the sizes of the image, which tells me there must be some way to get the attachment page link.

    Any help appreciated.

  5. Thanks! I needed this for the Types plugin’s file fields, which only contain the url. So glad that I found your solution for this.

  6. Pingback: Get all image IDs from the Media Library - WordPress BuddyPress Tweaks

  7. I’m working on a plugin which was using Pippin’s snippet, until I ran into issues with the guid as well. Thankful to read through the comments and find yours, which is working like a charm. Thank you!

  8. Pingback: Slug-based media-tag galleries in WordPress

  9. Thanks a lot for sharing this! It really helped me in a bind. However, right after I got out of that bind, I found out WordPress introduced a new attachment_url_to_postid function in 4.0 that does this very thing. Spread the word!

  10. Pingback: wordpress:How do I extract the Alt Text from an image attachment upload via the WordPress Options Framework Plugin? – Wordpress Questions

  11. I just wanted to say THANK YOU!!!
    This, combined with a few more lines of code, meant an easy solution for… drumroll… you guessed it! A customer coming from Thesis with Thesis postmeta featured images / display.

  12. Hi,

    I am new to wordpress and I am wondering if you could show me how to call this function and echo the results.

    This is what I have and it is not working.

    ….
    function pn_get_attachment_id_from_url( $attachment_url )…..

    end function….

    $results = pn_get_attachment_id_from_url( $attachment_id )

    echo $results

    • @Whichrtmej I see the name of the variable you are passing to pn_get_attachment_id_from_url() is named $attachment_id. I cannot see what the value of your $attachment_id variable is, but the function is expecting a URL, not an ID. If you had the ID already you would not need to use this function. 🙂

      If the value of $attachment_id actually contains the attachment URL, and not the ID, that should work, but the naming of your variable makes me suspect you are not passing in the URL of the attachment whose ID you want to find.

  13. Thank you for this assistance! I was looking for a way to integrate the Shortcodes Ultimate ‘Slide Link’ into another plugin that creates a slider and this was just what I needed.

    I don’t know if it helps anyone (or is terribly relevant, really) but, once I could get the ID, I could use a second call to the ‘wp_postmeta’ table to get to the SU link that can be added to media:


    function pn_get_attachment_link_from_id($su_code, $attachment_id) {
    global $wpdb;
    $attachment_link = $wpdb->get_var( $wpdb->prepare("SELECT DISTINCT wp_postmeta.meta_value as attachment_link FROM wp_postmeta WHERE wp_postmeta.meta_key = '%s' AND wp_postmeta.post_id = '%s'",$su_code,$attachment_id));
    return $attachment_link;
    }

    Then,

    $su_code = 'su_slide_link';
    $attachment_link = pn_get_attachment_link_from_id($su_code,$attachment_id);

    This way, I can add the link when using the images in other plugins. Yay!
    I could also change the parameter to “_wp_attachment_image_alt” to pull the ‘Alt tag’ which is very useful when things like some gallery plugins don’t set the alt tag automatically.

    Thanks again for posting this!

Leave a Reply

Your email address will not be published. Required fields are marked *