diff --git a/src/wp-admin/includes/nav-menu.php b/src/wp-admin/includes/nav-menu.php
index 18dcc97..951c03c 100644
--- a/src/wp-admin/includes/nav-menu.php
+++ b/src/wp-admin/includes/nav-menu.php
@@ -1057,3 +1057,39 @@ function wp_nav_menu_update_menu_items ( $nav_menu_selected_id, $nav_menu_select
 
 	return $messages;
 }
+
+/**
+ * If a JSON blob of navigation menu data is in POST data, expand it and inject
+ * it into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
+ *
+ * @since 4.5.1
+ */
+function wp_expand_nav_menu_post_data() {
+	if ( ! isset( $_POST['nav-menu-data'] ) ) {
+		return;
+	}
+	$data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
+	if ( ! is_null( $data ) && $data ) {
+		foreach ( $data as $post_input_data ) {
+			// For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`), derive the array path keys via regex.
+			if ( preg_match( '#([^\[]*)\[(.+)\]#', $post_input_data->name, $matches ) ) {
+				$array_bits = explode( '][', $matches[2] );
+				$_new_data = array();
+				for ( $i = count($array_bits) - 1; $i >= 0; $i -- ) {
+					if ( $i == count($array_bits) - 1 ) {
+						$_new_data[ $array_bits[$i] ] = wp_slash( $post_input_data->value );
+					} else {
+						$_i = array();
+						$_i[ $array_bits[$i] ] = $_new_data;
+						$_new_data = $_i;
+					}
+				}
+				$new_data = array();
+				$new_data[$matches[1]] = $_new_data;
+				$_POST = array_merge_recursive( $_POST, $new_data );
+			} else {
+				$_POST[ $post_input_data->name ] = wp_slash( $post_input_data->value );
+			}
+		}
+	}
+}
diff --git a/src/wp-admin/nav-menus.php b/src/wp-admin/nav-menus.php
index 7099e49..a037659 100644
--- a/src/wp-admin/nav-menus.php
+++ b/src/wp-admin/nav-menus.php
@@ -53,32 +53,8 @@ $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit';
  * If a JSON blob of navigation menu data is found, expand it and inject it
  * into `$_POST` to avoid PHP `max_input_vars` limitations. See #14134.
  */
-if ( isset( $_POST['nav-menu-data'] ) ) {
-	$data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
-	if ( ! is_null( $data ) && $data ) {
-		foreach ( $data as $post_input_data ) {
-			// For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`), derive the array path keys via regex.
-			if ( preg_match( '#([^\[]*)\[(.+)\]#', $post_input_data->name, $matches ) ) {
-				$array_bits = explode( '][', $matches[2] );
-				$_new_data = array();
-				for ( $i = count($array_bits) - 1; $i >= 0; $i -- ) {
-					if ( $i == count($array_bits) - 1 ) {
-						$_new_data[ $array_bits[$i] ] = wp_slash( $post_input_data->value );
-					} else {
-						$_i = array();
-						$_i[ $array_bits[$i] ] = $_new_data;
-						$_new_data = $_i;
-					}
-				}
-				$new_data = array();
-				$new_data[$matches[1]] = $_new_data;
-				$_POST = array_merge_recursive( $_POST, $new_data );
-			} else {
-				$_POST[ $post_input_data->name ] = wp_slash( $post_input_data->value );
-			}
-		}
-	}
-}
+wp_expand_nav_menu_post_data();
+
 switch ( $action ) {
 	case 'add-menu-item':
 		check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );
diff --git a/tests/phpunit/tests/menu/wpExpandNavMenuPostData.php b/tests/phpunit/tests/menu/wpExpandNavMenuPostData.php
new file mode 100644
index 0000000..9db1858
--- /dev/null
+++ b/tests/phpunit/tests/menu/wpExpandNavMenuPostData.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @group menu
+ */
+class Tests_Menu_WpExpandNavMenuPostData extends WP_UnitTestCase {
+
+	public function test_multidimensional_nested_array_should_expand() {
+		include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
+		if ( empty( $_POST ) ) {
+			$_POST = array();
+		}
+		$data = array();
+		$data[0] = new StdClass;
+		$data[0]->name = "would[1][do][the][trick]";
+		$data[0]->value = "yes";
+		$_POST['nav-menu-data'] = addslashes( json_encode( $data ) );
+		wp_expand_nav_menu_post_data();
+		$expected = array(
+			'nav-menu-data' => $_POST['nav-menu-data'],
+			'would' => array(
+				1 => array(
+					'do' => array(
+						'the' => array(
+							'trick' => 'yes'
+						)
+					)
+				)
+			)
+		);
+		$this->assertEquals( $expected, $_POST );
+	}
+
+	public function test_multidimensional_nested_array_should_expand_and_merge() {
+		include_once( ABSPATH . 'wp-admin/includes/nav-menu.php' );
+		if ( empty( $_POST ) ) {
+			$_POST = array();
+		}
+		$data = array();
+		$data[0] = new StdClass;
+		$data[0]->name = "would[1][do][the][trick]";
+		$data[0]->value = "yes";
+		$data[1] = new StdClass;
+		$data[1]->name = "would[2][do][the][trick]";
+		$data[1]->value = "yes";
+		$data[2] = new StdClass;
+		$data[2]->name = "would[2][do][the][job]";
+		$data[2]->value = "yes";
+		$_POST['nav-menu-data'] = addslashes( json_encode( $data ) );
+		wp_expand_nav_menu_post_data();
+		$expected = array(
+			'nav-menu-data' => $_POST['nav-menu-data'],
+			'would' => array(
+				1 => array(
+					'do' => array(
+						'the' => array(
+							'trick' => 'yes'
+						)
+					)
+				),
+				2 => array(
+					'do' => array(
+						'the' => array(
+							'trick' => 'yes',
+							'job' => 'yes'
+						)
+					)
+				)
+			)
+		);
+		$this->assertEquals( $expected, $_POST );
+	}
+
+}
