The challenge: Have an image URL, want its ID in the WordPress database

While working on new ideas for my plugin Quick Featured Images I had the need to get the ID of an uploaded image by its URL found in the post content.

To my surprise there was not such a built-in function in WordPress. So I finished a function which does this task. It has several properties:

  1. it tries to get the base file name of the image
  2. of any size (full, medium, thumbnail, custom size etc.)
  3. while ignoring image URLs to external servers and
  4. ignoring any query string in the image’s URL and
  5. looks up the new image URL in the database as post’s “Globally Unique Identifier” (column name: „guid“) and
  6. returns the corresponding ID as integer
  7. otherwise returns 0 (zero) to say „no such image“.

The solution

Here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
 * Takes an URL of an uploaded image 
 * and returns its post id, else 0
 *
 */
 function get_image_id_by_url ( $url ) {
    global $wpdb;
    $img_id = 0;
    /* get_site_url(): look for internal 
    images only, i.e. images from the 
    media library and no image embedded 
    by URL from external servers */
    /* ([^/]+)\.[a-z0-9]+$: get the 
    base file name without any 
    file extension */
        preg_match( '|' . get_site_url() . '|i', $url, $matches );
        // if site-owned image
        if ( isset( $matches ) and 0 < count( $matches ) ) {
            // delete optional query string
            $url = preg_replace( '/([^?]+).*/', '\1', $url ); 
            /* delete image dimensions
            informations, just take base 
            name and extension */
            $guid = preg_replace( '/(.+)-\d+x\d+\.(\w+)/', '\1.\2', $url ); 
            // look up its ID in the db
            $img_id = $wpdb->get_var( $wpdb->prepare( "SELECT `ID` FROM $wpdb->posts WHERE `guid` = '%s'", $guid ) );
        /* if it is not 0, false or 
        null: cast it to integer */
        if ( $img_id ) {
            // finally we have an id
            $img_id = intval( $img_id );
        }
    } // if $matches
    return $img_id;
}
/**
 * Takes an URL of an uploaded image 
 * and returns its post id, else 0
 *
 */
 function get_image_id_by_url ( $url ) {
	global $wpdb;
	$img_id = 0;
	/* get_site_url(): look for internal 
	images only, i.e. images from the 
	media library and no image embedded 
	by URL from external servers */
	/* ([^/]+)\.[a-z0-9]+$: get the 
	base file name without any 
	file extension */
		preg_match( '|' . get_site_url() . '|i', $url, $matches );
		// if site-owned image
		if ( isset( $matches ) and 0 < count( $matches ) ) {
			// delete optional query string
			$url = preg_replace( '/([^?]+).*/', '\1', $url ); 
			/* delete image dimensions
			informations, just take base 
			name and extension */
			$guid = preg_replace( '/(.+)-\d+x\d+\.(\w+)/', '\1.\2', $url ); 
			// look up its ID in the db
			$img_id = $wpdb->get_var( $wpdb->prepare( "SELECT `ID` FROM $wpdb->posts WHERE `guid` = '%s'", $guid ) );
		/* if it is not 0, false or 
		null: cast it to integer */
		if ( $img_id ) {
			// finally we have an id
			$img_id = intval( $img_id );
		}
	} // if $matches
	return $img_id;
}

Examples of usage

To use the function just take this line:

1
$id = get_image_id_by_url( $some_url );
$id = get_image_id_by_url( $some_url );

To check whether the returned value is a valid ID, just remember that the function returns a positive integer or the 0. If it returns 0 there was no image found.

The 0 has the same boolean value as ‚false‘.
A positive integer has the same boolean value as ‚true‘.

So just checking the returned value is enough to write a safe test. Here is an example:

1
2
3
4
5
6
7
8
$img_id = get_image_id_by_url( $some_url );
if ( $img_id ) {
    // do something ...
    set_post_thumbnail( $post_id, $img_id );
} else {
    // do otherthing ...
    echo 'The image could not be found in the database.';
}
$img_id = get_image_id_by_url( $some_url );
if ( $img_id ) {
	// do something ...
	set_post_thumbnail( $post_id, $img_id );
} else {
	// do otherthing ...
	echo 'The image could not be found in the database.';
}

Discussion

Lets talk about that in the comments.