0

I have not been able to find a reliable solution for how to lookup the id for attachments in the media library from a filename as Wordpress does not appear to provide such a function.

Most solutions rely on searching the GUID field in various tables, however there are issues with attachments uploaded with greater than 2560px resolution. Wordpress appends '-scaled' to the filename returned by functions like get_attached_file(), but this is not reflected in the guid database column.

I'd be grateful for a generic function that returns the attachment id when given a filename.

1 Answer 1

1

I worked this out eventually by tracing through the code for get_attached_file() to see where it was getting the filename from, and reverse engineered the following:

function get_attachment_id_by_filename($filename) {
    global $wpdb;
    $sql = $wpdb->prepare("SELECT * FROM  $wpdb->posts WHERE  post_type = 'attachment' and guid like %s order by post_date desc", "%$filename");
    $attachments = $wpdb->get_results($sql, OBJECT);
    return $attachments[0]->ID ?? false;
}

Note that it is possible the query will return more than one row if the same file basename exists in different media library folders. This routine will however only return the most recent found.

This works for everything I can throw at it so far, but welcome any issues people may be aware of with this solution.

3
  • 2
    I noticed you edited your answer, but your SQL query is still prone to SQL injections, (hence I deleted my previous comment,) so once again, you should either use $wpdb->prepare() or (less-preferred) escape the $filename value, because your function could be called from custom code you've got no control and if the code accidentally passed 90's as the file name value, then MySQL would throw a syntax error. :/
    – Sally CJ
    Apr 27 at 13:53
  • 2
    And if the file name was something like foo' OR 1=1 #, then you'd get the wrong result, in addition to MySQL selecting all the post meta (because of the SQL injection OR 1=1). So always use $wpdb->prepare() or at least, escape individual dynamic inputs used in the SQL statement.
    – Sally CJ
    Apr 27 at 13:55
  • Thanks Sally, I've updated the answer as you suggested with a prepare
    – dyg
    Apr 30 at 1:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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