如何通过附件名称/URL而非ID获取附件?
Got it, so you want to fetch WordPress attachments using their filename or a custom URL instead of the default numeric ID? Let's break down how to do this, including building on the code snippet you provided.
First: Understand Your Existing Code
The code you shared modifies attachment links to point to your site's homepage with an attachment_id parameter—this lets you access attachments via ID through a unified URL format:
function wpa_attachment_link( $link, $id ){ return home_url() . '/?attachment_id=' . $id; } add_filter( 'attachment_link', 'wpa_attachment_link', 10, 2 );
But to use names or custom URLs instead, we'll expand this functionality.
Step 1: Create User-Friendly Attachment URLs with Filenames
First, let's adjust the attachment links to use the file's name (instead of ID) for cleaner, more readable URLs. Replace your existing filter with this:
function wpa_custom_attachment_link( $link, $id ) { $attachment = get_post( $id ); $filename = basename( get_attached_file( $id ) ); // Strip the file extension for a cleaner URL (optional) $slug = pathinfo( $filename, PATHINFO_FILENAME ); return home_url( '/attachment/' . $slug ); } add_filter( 'attachment_link', 'wpa_custom_attachment_link', 10, 2 );
Now your attachment links will look like yoursite.com/attachment/my-vacation-photo instead of the ID-based version.
Step 2: Make WordPress Recognize the Custom URL
Next, we need to tell WordPress how to handle these new URLs and fetch the right attachment by filename. Add these functions to your theme's functions.php or a custom plugin:
// Add rewrite rule for our custom attachment URLs function wpa_attachment_by_name_rewrite() { add_rewrite_rule( 'attachment/([^/]+)/?$', 'index.php?attachment_name=$matches[1]', 'top' ); } add_action( 'init', 'wpa_attachment_by_name_rewrite' ); // Register the custom query variable function wpa_add_attachment_name_var( $vars ) { $vars[] = 'attachment_name'; return $vars; } add_filter( 'query_vars', 'wpa_add_attachment_name_var' ); // Fetch the attachment when the custom URL is accessed function wpa_load_attachment_by_name() { if ( get_query_var( 'attachment_name' ) ) { $filename_slug = get_query_var( 'attachment_name' ); // Look for attachments matching the filename (without extension) $attachments = get_posts( array( 'post_type' => 'attachment', 'meta_query' => array( array( 'key' => '_wp_attached_file', 'value' => $filename_slug, 'compare' => 'LIKE' ) ), 'posts_per_page' => 1 ) ); if ( $attachments ) { // Redirect to the actual attachment file URL wp_redirect( wp_get_attachment_url( $attachments[0]->ID ) ); exit; } else { // Trigger a 404 if no matching attachment is found global $wp_query; $wp_query->set_404(); status_header( 404 ); } } } add_action( 'template_redirect', 'wpa_load_attachment_by_name' );
Important: After adding this code, go to your WordPress admin > Settings > Permalinks and click "Save Changes" to flush the rewrite rules.
Step 3: Fetch Attachments by Filename Directly in Code
If you need to grab an attachment by filename within your theme/plugin code (without using the URL), use this helper function:
function wpa_get_attachment_by_filename( $filename ) { $attachments = get_posts( array( 'post_type' => 'attachment', 'meta_query' => array( array( 'key' => '_wp_attached_file', 'value' => $filename, 'compare' => 'LIKE' ) ), 'posts_per_page' => 1 ) ); return $attachments ? $attachments[0] : false; } // Usage example: $my_attachment = wpa_get_attachment_by_filename( 'my-vacation-photo.jpg' ); if ( $my_attachment ) { $attachment_url = wp_get_attachment_url( $my_attachment->ID ); // Do something with the URL here }
内容的提问来源于stack exchange,提问作者Gaurav Kumeriya

