I'm developing a theme which will grab and upload an image when a post is published, using the following function:

media_sideload_img( $url, $id, $description, 'src' );

The problem is, I often update my posts and this ends up with dozens of copies of the same image, which was uploaded several times with every post update.

Is there a way to check whether an attachment exists before uploading it to the server?

P.S: At the moment i'm using this function to get the ID of uploaded attachment:

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;

Since i have access to the filename that I'm grabbing (from the URL) and they are all unique ( filenames are in hash ), i could check for it's existence in database but I'm not good enough with SQL queries. If this is an option too, any help is appreciated.


I'm using this query to see if the file exists or not. Is it safe to use this? will it always return the right value?

$wpdb->get_var("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_value = '$img_name'");

2 Answers 2


I wonder if you're looking for the core attachment_url_to_postid() function that uses:

$sql = $wpdb->prepare(
    "SELECT post_id FROM $wpdb->postmeta 
         WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
$post_id = $wpdb->get_var( $sql );

Note the extra meta key _wp_attached_file check compared to your current snippet.

If you need to check if an image url is an existing thumbnail, then you can check my recent answer here.


Now I understand it better what you mean. The problem is that _wp_attached_file stores values like 2015/04/test.jpg, if you use year/month uploads, so you could try to search for the test.jpg file with

... WHERE meta_key = '_wp_attached_file' AND meta_value LIKE '%/test.jpg' 

in your custom snippet (watch out for possible SQL injections in your code).

Not sure what your setup is, but another approach might be to store successfully fetched and uploaded images in a more suitable way in the db that suits your needs.

  • Thanks, this is sort of similar to my query. The attachment_url_to_postid() returns false if the image is not uploaded, so i have to call another function to upload it right? I mean it doesn't upload the image if not existing, right?
    – Johansson
    Apr 1, 2017 at 18:00
  • I guess you mean media_sideload_image()? You could try to run a attachment_url_to_postid( $url ) check before it? @JackJohansson
    – birgire
    Apr 1, 2017 at 18:08
  • Yes exactly. My URLs are remote and don't belong to my own domain, so i'm not sure if attachment_url_to_postid() will work. However i can see this line $path = str_replace( $image_path['scheme'], $site_url['scheme'], $path ); in the source code which seems to replace the path with my blog's media library directory.
    – Johansson
    Apr 1, 2017 at 18:10
  • 1
    Yea, i had to disable year/moth organization to go through this. However i marked your answer as accepted since the provided function of yours helped me in this achievement. Thanks.
    – Johansson
    Apr 1, 2017 at 19:11
  • 1
    you're welcome, glad to hear you found a solution that works for you @JackJohansson
    – birgire
    Apr 1, 2017 at 19:23

I accepted @birgire's answer, however i solved it by approaching the problem this way:

function upload_image_as_attachment ($image_url, $post_id, $title) {
    $img_name = basename ($image_url);
    $local_url = wp_get_upload_dir()['path'].'/'.$img_name;
        $id = attachment_url_to_postid($local_url);
        return $id;
    } else {
        $attachment_src = media_sideload_image( $image_url, $post_id, $title,'src' );
        $id = attachment_url_to_postid($attachment_src);
        return $id;

This function takes an image URL and checks if the media is already uploaded. If not, uses media_sideload_image() to upload it and returns the ID of the uploaded attachment.

I have to mention that i needed to disable year/month organization of uploaded medias to achieve this.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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