Turn a URL into an Attachment / Post ID

Is there any way I can take a URL of an image and find the attachment or post id of that image in the database?

Here is the situation:

I’m in a loop going over all the ‘img’ tags that are surrounded by ‘a’ tags in my post content. if the src attribute of the ‘img’ tag does not match the href attribute of the outer ‘a’ tag, then i want to replace the ‘img’ tag. In doing this, if the ‘img’ that is to be removed is in the gallery, i want to delete that post, and then put my replacement ‘img’ in its place. I tried using a function like this:

function find_image_post_id($url) {
  global $wpdb;
  $postid = $wpdb->get_var($wpdb->prepare("SELECT DISTINCT ID FROM $wpdb->posts WHERE guid='$url'"));
  if ($postid) {
    return $postid;
  }
  return false;
}

This apparently is not right because the guid is ironically not globally unique. I had (earlier in the same script) uploaded a file with the same name (why? because it was higher resolution and i am trying to replace low resolution versions of the same image) and although wordpress will save the image with a different name in the directory, the guid’s were set to be the same. (possibly a bug).

Is there another technique I can use?

6

Massively improved function developed for plugin heavy on images:

if ( ! function_exists( 'get_attachment_id' ) ) {
    /**
     * Get the Attachment ID for a given image URL.
     *
     * @link   http://wordpress.stackexchange.com/a/7094
     *
     * @param  string $url
     *
     * @return boolean|integer
     */
    function get_attachment_id( $url ) {

        $dir = wp_upload_dir();

        // baseurl never has a trailing slash
        if ( false === strpos( $url, $dir['baseurl'] . "https://wordpress.stackexchange.com/" ) ) {
            // URL points to a place outside of upload directory
            return false;
        }

        $file  = basename( $url );
        $query = array(
            'post_type'  => 'attachment',
            'fields'     => 'ids',
            'meta_query' => array(
                array(
                    'key'     => '_wp_attached_file',
                    'value'   => $file,
                    'compare' => 'LIKE',
                ),
            )
        );

        // query attachments
        $ids = get_posts( $query );

        if ( ! empty( $ids ) ) {

            foreach ( $ids as $id ) {

                // first entry of returned array is the URL
                if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
                    return $id;
            }
        }

        $query['meta_query'][0]['key'] = '_wp_attachment_metadata';

        // query attachments again
        $ids = get_posts( $query );

        if ( empty( $ids) )
            return false;

        foreach ( $ids as $id ) {

            $meta = wp_get_attachment_metadata( $id );

            foreach ( $meta['sizes'] as $size => $values ) {

                if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
                    return $id;
            }
        }

        return false;
    }
}

Leave a Comment