Upload Image and set as Featured Image Through Functions in WordPress

This function will let you upload an image to a specific post and assign it as the featured image/post thumbnail. You can do this in a plugin or theme, using images that are contained within your package.

If you want to upload images from your theme or plugin without attaching them to any post, see this instead.

The function:

 * Sideload an image and set it as the featured image.
 * Upload an image, attach it to a post, and set it as the featured image (the post thumbnail).
 * Additional functionality: ability to pass $post_data to override values in wp_insert_attachment
 * @param string $url (required) The URL of the image to download
 * @param int $post_id (required) The post ID the media is to be associated with
 * @param array $post_data (optional) Array of key => values for wp_posts table (ex: 'post_title' => 'foobar', 'post_status' => 'draft')
 * @return int|object The ID of the attachment or a WP_Error on failure

function my_attach_external_image( $url = null, $post_id = null, $post_data = array() ) {
	    if ( !$url || !$post_id ) return new WP_Error('missing', "Need a valid URL and post ID...");
	    require_once( ABSPATH . 'wp-admin/includes/file.php' );
	    // Download file to temp location, returns full server path to temp file, ex; /home/user/public_html/mysite/wp-content/26192277_640.tmp
	    $tmp = download_url( $url );
	    // If error storing temporarily, unlink
	    if ( is_wp_error( $tmp ) ) {
	        @unlink($file_array['tmp_name']);   // clean up
	        $file_array['tmp_name'] = '';
	        return $tmp; // output wp_error
	    preg_match('/[^\?]+\.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $url, $matches);    // fix file filename for query strings
	    $url_filename = basename($matches[0]);                                                  // extract filename from url for title
	    $url_type = wp_check_filetype($url_filename);                                           // determine file type (ext and mime/type)
	    // assemble file data (should be built like $_FILES since wp_handle_sideload() will be using)
	    $file_array['tmp_name'] = $tmp;                                                         // full server path to temp file

	        $file_array['name'] = $url_filename;
	    // set additional wp_posts columns
	    if ( empty( $post_data['post_title'] ) ) {
	        $post_data['post_title'] = basename($url_filename, "." . $url_type['ext']);         // just use the original filename (no extension)
	    // make sure gets tied to parent
	    if ( empty( $post_data['post_parent'] ) ) {
	        $post_data['post_parent'] = $post_id;
	    // required libraries for media_handle_sideload
	    require_once(ABSPATH . 'wp-admin/includes/file.php');
	    require_once(ABSPATH . 'wp-admin/includes/media.php');
	    require_once(ABSPATH . 'wp-admin/includes/image.php');
	    // do the validation and storage stuff
	    $att_id = media_handle_sideload( $file_array, $post_id, null, $post_data );             // $post_data can override the items saved to wp_posts table, like post_mime_type, guid, post_parent, post_title, post_content, post_status
	    // If error storing permanently, unlink
	    if ( is_wp_error($att_id) ) {
	        @unlink($file_array['tmp_name']);   // clean up
	        return $att_id; // output wp_error
	    // set as post thumbnail if desired
	        set_post_thumbnail($post_id, $att_id);
	    return $att_id;


Place the function above in your plugin or theme. To use it, make sure it only gets fired once since it will upload the image each time it gets fired. So, if you’re using it in a theme, hook it to “after_switch_theme” to make sure it only works once.

If you’re using it in a plugin, put it inside your activation function and use the “register_activation_hook” to call it.

The following example is for use in a theme so it’s hooked to “after_switch_theme”. This uploads 3 images and assigns each one as the “featured image” to a different post.

The function, “my_attach_external_image”, is called on lines 10, 11, and 12 below. The 1st parameter is the URL of the image to attach. In this example, the 3 images are inside the theme’s images directory. Adjust the 1st parameter show the location and filename of your image.

The 2nd parameter is the post ID of the post that the image should be attached to. The 3 posts in this example are being created by the theme, so we have the post IDs in a variable. Change the 2nd parameter according to your needs.

function my_theme_activation() {
	 * Attach images and set them as featured.

	// before uploading images, remove max time limit, then return to default limit
	$default = ini_get('max_execution_time');

	my_attach_external_image( get_template_directory_uri().'/images/image-1.jpg', $post_id_1 );
	my_attach_external_image( get_template_directory_uri().'/images/image-2.jpg', $post_id_2 );
	my_attach_external_image( get_template_directory_uri().'/images/image-3.jpg', $post_id_3 );

	// revert to default max time limit

add_action('after_switch_theme', 'my_theme_activation');

See more:


We've 2 Responses

  1. March 3rd, 2018 at 3:48 am

    Hello Isabel,

    very nice job.. you save my day.. i have search a while for this code. i had problems with the max_execution_time, now it works fine.


    ps. hows with image exists? Abort or Override?


Leave a Reply to Wordpress Developer Cancel reply

Your email address will not be published. All comments will be moderated.

Please wrap code in "code" bracket tags like this: