Especially when developing plugins or theme settings that make use of the WordPress media uploader to upload and insert images, being able to retrieve the ID of the image uploaded can be extremely useful. By grabbing the image (attachment) ID, you suddenly have a lot more control over what you can do with the image, such as display one of the different sizes that WordPress generates when the image is uploaded.
This is a little function I wrote while on the train home from Chicago.

// retrieves the attachment ID from the file URL
function pippin_get_image_id($image_url) {
	global $wpdb;
	$attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url )); 
        return $attachment[0]; 
}

Simply pass the URL of the image ID you wish to retrieve. Once you’ve done that, you could do the following to retrieve the auto-generated thumbnail size of the image:

// set the image url
$image_url = 'http://yoursite.com/wp-content/uploads/2011/02/14/image_name.jpg';
 
// store the image ID in a var
$image_id = pippin_get_image_id($image_url);
 
// retrieve the thumbnail size of our image
$image_thumb = wp_get_attachment_image_src($image_id, 'thumbnail');
 
// display the image
echo $image_thumb[0];

Enjoy!

  1. Chris

    Does it work with image URLs that are not the main image? Resized versions, etc.

    • Pippin

      No, you will need the original URL, but you can then use the ID to get the other sizes.

  2. AJ

    Very useful. Great work!

  3. Duane

    Hey Pippin,

    This is a rad little snippet. I rewrote it slightly to directly retrieve the desired thumb size as it can become frustrating to continually rewrite the last 3 steps.

    function pippin_get_image_id( $image_url, $size ) {
     
    	global $wpdb;
    	$prefix = $wpdb->prefix;
    	$attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM " . $prefix . "posts" . " WHERE guid='" . $image_url . "';" ) );
    	$image_thumb = wp_get_attachment_image_src( $attachment[0], $size );
    	return $image_thumb[0];
    }
    • Pippin

      Excellent!

  4. Ruven

    I tried this out, but it seems that the “guid” is not in all cases the URL to the picture.

    • Pippin

      That is true, the guid column will not always work. There was a tutorial someone posted not too long ago with a better way to do this, but I don’t remember which site it was on unfortunately.

    • Philip Newcomer

      After combining some code from several other people who have posted about this online, here’s a function I wrote that doesn’t use GUIDs, and even works with image thumbnail URLs:

      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+xd+(?=.(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;
      }
    • Pippin

      Looks great! FYI, you can post code by wrapping it in PRE tags.

    • Philip Newcomer

      I see. The PRE tag wasn’t in the list of allowed tags below the comment box, so I used CODE. ๐Ÿ™‚

    • Pippin

      I’ve updated the code to fix the error.

    • Melinda

      That works again. Thank you so much for your help!

  5. Name

    ty for update!

    • Name

      Take it back, nothing has changed? Same 3.5 update problem

  6. Name

    okay, jk it works. maybe put your example function in one block so it doesn’t look so janky? Thanks for this btw.

    • Pippin

      Whoops, fixed!

  7. Eric Daams

    Hi Pippin,

    Great tip. Using this to get the attachment ID of a logo uploaded via the WP customizer.

    One quick question: Is there a reason why you use $wpdb->prefix instead of just using $wpdb->posts inside the SQL? Since it’s a default table should $wpdb->posts always have the correct prefix anyway?

    Cheers,
    Eric

    • Pippin

      Nope, no reason ๐Ÿ™‚

  8. Melinda McCaw

    How do I use this to display the thumbnail of a custom image size I created using add_image_size? For example I am trying to display the thumbnail size for the ‘home-page-slide’ size that was created using the code below.

    This code works great to display the thumbnail of a full size image but if I select the Home Page Slide size there is not a thumbnail that displays. (I am trying to display these thumbnails in the meta box I have created in an image slider).


    //Add Post Thumbnail Support
    if (function_exists('add_theme_support')) { // as of WP 2.9
    add_theme_support( 'post-thumbnails', array( 'newsletter','homeslider' ) );//activate thumbnails for these custom post types
    add_image_size('newsletterlg', 300, 200, true);//image size for display in post
    add_image_size('newsletterthumb', 132, 107, true);//thumbnail for main newsletter page
    add_image_size( 'home-page-slide', 1200, 355, true );
    add_image_size( 'product-slide', 203, 131, true );
    }

    //add custom image sizes to Sizes selection in media uploader
    function custom_in_post_images( $args ) {
    $custom_images = array('home-page-slide' => 'Home Page Slide', 'product-slide' => 'Product Slide'); return array_merge( $args, $custom_images );
    }
    add_filter( 'image_size_names_choose', 'custom_in_post_images' );

  9. Tom

    Quick spot. Current code has HTML number instead of “->” which causes a straight copy/paste to fail

  10. Carlo

    Hi Pippin,

    great tip indeed!

    Just wanna try a little further… does it only work with images or even with other attachment type (such as pdf i.e.)?

    thanks
    and again, great tip!
    Bye
    Carlo

    • Pippin

      Yep!

  11. OriginalEXE

    Looks like your “greater than” sign got replaced by html name on fourth line of first code snippet.

  12. The Frosty

    Create little snippet! I’ve modified it slightly for my needs.

    function url_to_attachmentid( $image_url ) {
    if ( empty( $image_url ) )
    return null;

    global $wpdb;

    $attachment = wp_cache_get( ‘featured_column_thumbnail_’ . md5( $image_url ), null );
    if ( false === $attachment ) {
    $attachment = $wpdb->get_col( $wpdb->prepare( “SELECT ID FROM $wpdb->posts WHERE guid = ‘%s’;”, $image_url ) );
    wp_cache_add( ‘featured_column_thumbnail_’ . md5( $image_url ), $attachment, null );
    }

    return !empty( $attachment ) ? $attachment[0] : null;
    }

    • Pippin

      Nice ๐Ÿ˜€

  13. Andy Warren

    I’ve used this many times, always without issue. Today, I moved a site from one server to another (Bluehost to GoDaddy), and now it just returns empty src=”” for all images. Its still working fine on the copy of the site on Bluehost, but the copy on GoDaddy gives me

    Any thought son this? Totally confused.

  14. AliceAlice

    Hello,
    I would be really really happy to have an anwser, even if it’s impossible ๐Ÿ™‚

    I had a developper who export an old php blog (it wasn’t a cms) and build a new wordpress really great. He left me during the process : I have to export this blog into 2 MU sites. I already did that, it’s not a problem. But! Big but !
    He didn’t worked with the good practice on librairy. He worked with ID (that what he said).
    So I have my posts with good thumbnail, even if he put aaaaall images (8000) in a same folder (/upload without under folder with dates).
    When I want to export a part of this blog in xml I think wp can’t find images so nothing in xml code on url images, and impossible to import…

    Do you see my problem and is it possible to make something…?
    The posts have a featured image, but I don’t know where it’s declared, because xml export everything but images.

    I have to find a way to tell wp to export real image it has in thumbnail/featured image (and not the way it used to, in folder/yyyy/mm/dd) OR something to rebuilt the librairy and put images in good folders…

    Thank you a lot for your answer.
    I have 1000 posts to repost in 2 differents domains, and it could be really long to reimport featured images with my hands :/

  15. talentedaamer

    simple and perfect, good work (y)

  16. Mikki

    Thanks for finally writing about >Retrieve Attachmewnt
    ID from Imagte URL | Pippins Plugins <Loved it!

  17. Marta

    Hi everyone. I’ve got much simpler way to get another size of image without id and without sql and this kind of stuff.

    Just use:
    $new_image_url = str_replace(“.jpg”, “-150×150.jpg”, $image_url);

    In uploads you can check wich sizes of images do you have, and thats all ๐Ÿ™‚

    Hope helped anyone ๐Ÿ™‚

  18. Brian Hill

    Yep! Worked – I like you made the function name with word “pippin”. Nice way to branding

  19. mihaibadic

    AMAAAAZIIIIIIIIIIIIIIIIIINGGGGGGGGG YOU RULE

  20. calvinlazer

    Every time I found your article on google, I feels I ‘ll get my answer. really amazing efforts you put on your article to make it easier to understand.

  21. Calvin Lazer

    Every time I found your article on google, I feels I โ€˜ll get my answer. really amazing efforts you put on your article to make it easier to understand.

  22. Trovalost.it

    You can get this more faster using a MySQL index on guid,post_type columns, I suppose.

Comments are closed.