Title: WP_REST_Attachments_Controller::upload_from_file
Published: December 6, 2016
Last modified: February 24, 2026

---

# WP_REST_Attachments_Controller::upload_from_file( array $files, array $headers, string|null $time = null ): array|󠀁[WP_Error](https://developer.wordpress.org/reference/classes/wp_error/)󠁿

## In this article

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

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

Handles an upload via multipart/form-data ($_FILES).

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

 `$files`arrayrequired

Data from the `$_FILES` superglobal.

`$headers`arrayrequired

HTTP headers from the request.

`$time`string|nulloptional

Time formatted in `'yyyy/mm'`.

Default:`null`

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

 array|[WP_Error](https://developer.wordpress.org/reference/classes/wp_error/) Data
from [wp_handle_upload()](https://developer.wordpress.org/reference/functions/wp_handle_upload/).

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

    ```php
    protected function upload_from_file( $files, $headers, $time = null ) {
    	if ( empty( $files ) ) {
    		return new WP_Error(
    			'rest_upload_no_data',
    			__( 'No data supplied.' ),
    			array( 'status' => 400 )
    		);
    	}

    	// Verify hash, if given.
    	if ( ! empty( $headers['content_md5'] ) ) {
    		$content_md5 = array_shift( $headers['content_md5'] );
    		$expected    = trim( $content_md5 );
    		$actual      = md5_file( $files['file']['tmp_name'] );

    		if ( $expected !== $actual ) {
    			return new WP_Error(
    				'rest_upload_hash_mismatch',
    				__( 'Content hash did not match expected.' ),
    				array( 'status' => 412 )
    			);
    		}
    	}

    	// Pass off to WP to handle the actual upload.
    	$overrides = array(
    		'test_form' => false,
    	);

    	// Bypasses is_uploaded_file() when running unit tests.
    	if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) {
    		$overrides['action'] = 'wp_handle_mock_upload';
    	}

    	$size_check = self::check_upload_size( $files['file'] );
    	if ( is_wp_error( $size_check ) ) {
    		return $size_check;
    	}

    	// Include filesystem functions to get access to wp_handle_upload().
    	require_once ABSPATH . 'wp-admin/includes/file.php';

    	$file = wp_handle_upload( $files['file'], $overrides, $time );

    	if ( isset( $file['error'] ) ) {
    		return new WP_Error(
    			'rest_upload_unknown_error',
    			$file['error'],
    			array( 'status' => 500 )
    		);
    	}

    	return $file;
    }
    ```

[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/6.9.4/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php#L1400)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php#L1400-L1453)

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

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

Determine if uploaded file exceeds space quota on multisite.

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

Wrapper for [_wp_handle_upload()](https://developer.wordpress.org/reference/functions/_wp_handle_upload/) .

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

Retrieves the translation of $text.

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

Checks whether the given variable is a WordPress Error.

  | 
| [WP_Error::__construct()](https://developer.wordpress.org/reference/classes/wp_error/__construct/)`wp-includes/class-wp-error.php` |

Initializes the error.

  |

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

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

Inserts the attachment post in the database. Does not update the attachment meta.

  |

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

| Version | Description | 
| [6.6.0](https://developer.wordpress.org/reference/since/6.6.0/) | Added the `$time` parameter. | 
| [4.7.0](https://developer.wordpress.org/reference/since/4.7.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%2Fupload_from_file%2F)
before being able to contribute a note or feedback.