Title: WP_REST_Attachments_Controller::get_attachment_upload_subdir
Published: August 20, 2026

---

# WP_REST_Attachments_Controller::get_attachment_upload_subdir( string $attached_file ): string|null

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#wp--skip-link--target)

Returns the uploads subdirectory an attachment is stored in.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#description)󠁿

Used to place a sideloaded file alongside the attachment it extends. The result 
is concatenated into a filesystem path by the caller, so it is returned only when
the attachment resolves inside the uploads directory and the stored path is well
formed.

## 󠀁[Parameters](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#parameters)󠁿

 `$attached_file`stringrequired

Absolute path to the attached file.

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#return)󠁿

 string|null Subdirectory beginning with a slash, an empty string when the attachment
sits in the base directory, or null when the attachment is not inside the uploads
directory.

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#source)󠁿

    ```php
    protected function get_attachment_upload_subdir( string $attached_file ): ?string {
    	$uploads = wp_get_upload_dir();
    	if ( empty( $uploads['basedir'] ) ) {
    		return null;
    	}

    	$basedir  = untrailingslashit( wp_normalize_path( $uploads['basedir'] ) );
    	$file_dir = wp_normalize_path( dirname( $attached_file ) );

    	/*
    	 * The attachment's directory must be the uploads base directory itself
    	 * or a directory inside it. The trailing slash in the prefix comparison
    	 * keeps a sibling directory that merely shares the prefix (for example
    	 * 'uploads-elsewhere' next to 'uploads') from matching.
    	 */
    	if ( $file_dir !== $basedir && ! str_starts_with( $file_dir, trailingslashit( $basedir ) ) ) {
    		return null;
    	}

    	$subdir = (string) substr( $file_dir, strlen( $basedir ) );

    	// A prefix match alone does not rule out a path that climbs back out.
    	if ( in_array( '..', explode( '/', $subdir ), true ) ) {
    		return null;
    	}

    	return $subdir;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.1/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php#L3204)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.1/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php#L3204-L3231)

## 󠀁[Related](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_get_upload_dir()](https://developer.wordpress.org/reference/functions/wp_get_upload_dir/)`wp-includes/functions.php` |

Retrieves uploads directory information.

  | 
| [untrailingslashit()](https://developer.wordpress.org/reference/functions/untrailingslashit/)`wp-includes/formatting.php` |

Removes trailing forward slashes and backslashes if they exist.

  | 
| [wp_normalize_path()](https://developer.wordpress.org/reference/functions/wp_normalize_path/)`wp-includes/functions.php` |

Normalizes a filesystem path.

  | 
| [trailingslashit()](https://developer.wordpress.org/reference/functions/trailingslashit/)`wp-includes/formatting.php` |

Appends a trailing slash.

  |

[Show 1 more](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#)

| Used by | Description | 
| [WP_REST_Attachments_Controller::sideload_item()](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/sideload_item/)`wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php` |

Side-loads a media file without creating a new attachment.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_rest_attachments_controller/get_attachment_upload_subdir/?output_format=md#changelog)󠁿

| Version | Description | 
| [7.1.0](https://developer.wordpress.org/reference/since/7.1.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_rest_attachments_controller%2Fget_attachment_upload_subdir%2F)
before being able to contribute a note or feedback.