最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Download an image from a webpage to the default uploads folder

matteradmin8PV0评论

I am writing a custom theme/plugin in which I need to download images programatically from certain webpages to the upload folder and then insert them as part of the post.

So, I was able to find the image url's programatically, and then I need to save them to the upload folder under wp-content, however that folder has specific WordPress folder structure inside it for the saved images.

Now my question is, is there a WordPress API or function or method that will allow me to download images from the web and save them to the uploads folder? And if so, what is it.

Otherwise, what should I do to save those images?

So far, I am doing this

$filetype = wp_check_filetype(basename($image_file_name), null );

$upload_dir = wp_upload_dir();

$attachment = array(
    'guid' => $upload_dir['url'] . '/' . basename( $image_file_name ), 
    'post_mime_type' => $filetype['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($image_file_name)),
    'post_content' => '',
    'post_status' => 'inherit'
);

$attachment_id = wp_insert_attachment( $attachment, $image_file_name, $post_id );

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

wp_update_attachment_metadata( $attachment_id,  $attachment_data );
set_post_thumbnail( $post_id, $attachment_id );

But the above code is giving me the following error

imagejpeg(.jpg): failed to open stream: HTTP wrapper does not support writeable connections in C:\dev\wordpress\pterodactylus\wp-includes\class-wp-image-editor.php on line 334

And after further investigation, it looks like the error is cause by

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

And after even further investigation, the documentation for wp_insert_attachment() states that The file MUST be on the uploads directory in regards to the $image_file_name

So, how do I download an image and save it to my post correctly?

Thanks a lot.

I am writing a custom theme/plugin in which I need to download images programatically from certain webpages to the upload folder and then insert them as part of the post.

So, I was able to find the image url's programatically, and then I need to save them to the upload folder under wp-content, however that folder has specific WordPress folder structure inside it for the saved images.

Now my question is, is there a WordPress API or function or method that will allow me to download images from the web and save them to the uploads folder? And if so, what is it.

Otherwise, what should I do to save those images?

So far, I am doing this

$filetype = wp_check_filetype(basename($image_file_name), null );

$upload_dir = wp_upload_dir();

$attachment = array(
    'guid' => $upload_dir['url'] . '/' . basename( $image_file_name ), 
    'post_mime_type' => $filetype['type'],
    'post_title' => preg_replace('/\.[^.]+$/', '', basename($image_file_name)),
    'post_content' => '',
    'post_status' => 'inherit'
);

$attachment_id = wp_insert_attachment( $attachment, $image_file_name, $post_id );

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

wp_update_attachment_metadata( $attachment_id,  $attachment_data );
set_post_thumbnail( $post_id, $attachment_id );

But the above code is giving me the following error

imagejpeg(http://wscdn.bbc.co.uk/worldservice/assets/images/2013/07/21/130721173402_egypts_new_foreign_minister_fahmy_304x171_reuters-150x150.jpg): failed to open stream: HTTP wrapper does not support writeable connections in C:\dev\wordpress\pterodactylus\wp-includes\class-wp-image-editor.php on line 334

And after further investigation, it looks like the error is cause by

$attachment_data = wp_generate_attachment_metadata( $attachment_id, $image_file_name );

And after even further investigation, the documentation for wp_insert_attachment() states that The file MUST be on the uploads directory in regards to the $image_file_name

So, how do I download an image and save it to my post correctly?

Thanks a lot.

Share Improve this question edited Nov 21, 2015 at 0:06 Greeso asked Jul 21, 2013 at 23:01 GreesoGreeso 2,2347 gold badges33 silver badges57 bronze badges 2
  • I had issues with this when it was permissions issue on the images in the uploads directory - they needed to be owned by the server user (e.g. www-data on apache/linux) – icc97 Commented Dec 4, 2013 at 11:52
  • this WordPress support topic has more info – icc97 Commented Dec 4, 2013 at 12:20
Add a comment  | 

4 Answers 4

Reset to default 15

I recently had to do this via a nightly cron script for a social media stream. $parent_id is the ID of the post you want to attach the image to.

function uploadRemoteImageAndAttach($image_url, $parent_id){

    $image = $image_url;

    $get = wp_remote_get( $image );

    $type = wp_remote_retrieve_header( $get, 'content-type' );

    if (!$type)
        return false;

    $mirror = wp_upload_bits( basename( $image ), '', wp_remote_retrieve_body( $get ) );

    $attachment = array(
        'post_title'=> basename( $image ),
        'post_mime_type' => $type
    );

    $attach_id = wp_insert_attachment( $attachment, $mirror['file'], $parent_id );

    require_once(ABSPATH . 'wp-admin/includes/image.php');

    $attach_data = wp_generate_attachment_metadata( $attach_id, $mirror['file'] );

    wp_update_attachment_metadata( $attach_id, $attach_data );

    return $attach_id;

}

ex:

uploadRemoteImageAndAttach('http://some-external-site/the-image.jpg', 122);

You have no posted the code used to fetch and save the image, so is impossible to say where is the error.

Try this code for grab and save the image:

function my_grab_image($url = NULL, $name = NULL ) {
  $url = stripslashes($url);
  if ( ! filter_var($url, FILTER_VALIDATE_URL) ) return false;
  if ( empty($name )) $name = basename($url);
  $dir = wp_upload_dir();
  $filename = wp_unique_filename( $uploads['path'], $name, NULL );
  $filetype = wp_check_filetype($filename, NULL );
  if ( ! substr_count($filetype['type'], 'image') ) return false;
  try {
    $image = my_fetch_image($url);
    if ( ! is_string($image) || empty($image) ) return false;
    $save = file_put_contents( $dir['path'] . "/" . $filename, $image );
    if ( ! $save ) return false;
    return $dir['path'] . "/" . $filename;
  } catch ( Exception $e ) {
    // echo $e->getMessage(); // Is a good idea log this error
    return false;
  }
}

function my_fetch_image($url) {
  if ( function_exists("curl_init") ) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $image = curl_exec($ch);
    curl_close($ch);
    return $image;
  } elseif ( ini_get("allow_url_fopen") ) {
    $image = file_get_contents($url, false);
    return $image;
  } else {
    throw new Exception('curl is not available and fopen url is disallowed');
  }
}

Then simply use these functions in combination with your code, like so:

$image_file_name =  @my_grab_image('http://this.is.the.image.url/image.jpg');
if ( $image_file_name && file_exists($image_file_name) ) {
  // PUT HERE YOUR CODE
}

Remember also that you must to include wp-admin/includes/image.php in your code for the function wp_generate_attachment_metadata() to work, see the Codex

Hope this help, but please note that all the code here is not tested.

You can use this function to remote upload an image to uploads folder and set it as featured image.

function set_remote_featured_image($file, $post_id) {
    if ( ! empty($file) ) {
        // Download file to temp location
        $tmp = download_url( $file );

        // Set variables for storage
        // fix file filename for query strings
        preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $file, $matches );
        $file_array['name'] = basename($matches[0]);
        $file_array['tmp_name'] = $tmp;

        // If error storing temporarily, unlink
        if ( is_wp_error( $tmp ) ) {
            @unlink($file_array['tmp_name']);
            $file_array['tmp_name'] = '';
        }

        // do the validation and storage stuff
        $id = media_handle_sideload( $file_array, $post_id, $desc );
        // If error storing permanently, unlink
        if ( is_wp_error($id) ) {
            @unlink($file_array['tmp_name']);
            return $id;
        }

        set_post_thumbnail( $post_id, $id );
    }
}

Usage:

set_remote_featured_image("http://example/image.jpg", 1);

Just use default wp (v2.6.0+) function:

media_sideload_image( $file, $post_id, $desc, $return );

Post a comment

comment list (0)

  1. No comments so far