WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to upload a image and set it as a featured image in a post. What i tried was this:

$image_id = media_sideload_image($image_url, $post_id, $post_id);
update_post_meta($post_id, '_thumbnail_id', $image_id);

But media_sideload_image() is not returning the image_id, but the render html image. How can I get the image_id??

share|improve this question

Here's code that should serve as an example on how to bypass this limitation using action hooks:

function new_attachment($att_id){
    // the post this was sideloaded into is the attachments parent!
    $p = get_post($att_id);

// add the function above to catch the attachments creation

// load the attachment from the URL
media_sideload_image($image_url, $post_id, $post_id);

// we have the Image now, and the function above will have fired too setting the thumbnail ID in the process, so lets remove the hook so we don't cause any more trouble 

The premise is that when media_sideload_image is ran, it downloads the image, adds it as an attachment, then attaches that attachment post to the post whose ID you provided($post_id). Your issue is that it does not provide the newly created attachment posts ID, but, when an attachment is created, an action is fired containing that ID, and from that we can figure out the ID of the post ($post_id), and set the featured image.

share|improve this answer
Brilliant! That helped so much. – mattrepublic Dec 11 '14 at 17:43
If this answers your question could you mark it as correct? – Tom J Nowell Dec 11 '14 at 19:07

@Tom J Nowell's answer is spot on. I found another alternative (using different functions) explained here but I like this one more.

In my case I have an array of $posts with all the posts I want to insert and a separate $media (same $nid keys as $posts) with the media. My code is the same solution as Tom's but refactored to use an anonymous function:

foreach( $posts as $nid=>$post )
    $posts[$nid]['ID'] = wp_insert_post( $post );

foreach( $posts as $nid=>$post )
    foreach( $media[$nid] as $m=>$mitem ) {

        if( 0 == $m ) add_action( 'add_attachment',
            function( $att_id ) use ($posts, $nid, $mitem) {
                update_post_meta($posts[$nid]['ID'], '_thumbnail_id', $att_id);
                $posts[$nid]['media_urls'][] = $mitem['url'];
        media_sideload_image($mitem['url'], $post['ID']);
        remove_all_actions( 'add_attachment' );

In my case I assume the 1st item in each $media[$nid] shuold be the featured image of its post.

WordPress shouold definitely change media_sideload_image() so it returns the $id . In fact the function has it at hand, see the source here. In fact there's a track ticket for this and they even have patches to apply this to your core in the mean time if you want.

share|improve this answer

I've build a function to get the ID from DB, searching by URL.

function get_attachment_id_from_src ($image_src) {
  global $wpdb;
  $query = "SELECT ID FROM {$wpdb->posts} WHERE guid='$image_src'";
  $id = $wpdb->get_var($query);
  return $id;

You can get URL (insted of html code) with a fourth paramenter set to 'src' Codex: media_sideload_image()

$src = media_sideload_image($url, $item_id, $desc,'src');
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.