Title: WP_View_Config_Data::merge_properties
Published: August 20, 2026

---

# WP_View_Config_Data::merge_properties( mixed $current, mixed $incoming, bool $replace_lists ): mixed

## In this article

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

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

This function’s access is marked private. This means it is not intended for use 
by plugin or theme developers, only by core. It is listed here for completeness.

Merges an incoming value into the current one, recursing by value shape.

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

This is the core of the merge algorithm and is applied at every nesting level: a
scalar (or `null`) in $incoming replaces $current outright, an associative array
merges key by key (recursing here for each key, with a `null` value deleting that
key), and a list either replaces $current wholesale ($replace_lists) or merges into
it by member identity. The $replace_lists flag is carried down through associative
nesting so that, under replace(), every list reached along the way is swapped wholesale.

An array in $incoming only merges into a current value of the same shape.
A non-
empty mismatch — an associative array where a list lives, or a non-empty list where
an associative value lives — is reported with [_doing_it_wrong()](https://developer.wordpress.org/reference/functions/_doing_it_wrong/)
and leaves the current value unchanged, so a malformed patch cannot silently destroy
configuration. An empty array is shape-ambiguous and merges nothing, so it is a 
no-op: clearing a list is spelled replace() with an empty list, and resetting a 
key is spelled `null`.

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

 `$current`mixedrequired

The current value.

`$incoming`mixedrequired

The incoming value.

`$replace_lists`boolrequired

Whether a list in $incoming replaces the current list wholesale instead of merging
into it by member identity.

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

 mixed The merged value.

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

    ```php
    private function merge_properties( $current, $incoming, $replace_lists ) {
    	// Scalar properties are merged as-is.
    	if ( ! is_array( $incoming ) ) {
    		return $incoming;
    	}

    	// Numerical indexed arrays are expected to be lists (sequential integer keys starting at 0).
    	if ( array_is_list( $incoming ) ) {
    		// A non-empty list only lands where a list (or nothing) lives, under
    		// merge() and replace() alike. An empty array is shape-ambiguous and
    		// exempt, so replace() with an empty list can still clear a list.
    		if ( array() !== $incoming && is_array( $current ) && ! array_is_list( $current ) && array() !== $current ) {
    			_doing_it_wrong(
    				__METHOD__,
    				esc_html__( 'A view configuration patch value must match the shape of the value it patches: a list merges into a list, and an associative array into an associative array.' ),
    				'7.1.0'
    			);
    			return $current;
    		}

    		// replace() takes an incoming list as-is; merge() merges it by member identity.
    		if ( $replace_lists ) {
    			// As-is except for nulls: a list swapped in wholesale has no
    			// existing leaf for a null to delete (the same rationale as
    			// set()), so a null member is dropped rather than stored.
    			return $this->strip_nulls( $incoming );
    		}

    		// An empty list has no members to merge, and an empty array is
    		// shape-ambiguous, so merging one is a no-op rather than a reset.
    		if ( array() === $incoming ) {
    			return $current;
    		}

    		return $this->merge_list_by_identity(
    			is_array( $current ) && array_is_list( $current ) ? $current : array(),
    			$incoming
    		);
    	}

    	// Consider any other array as associative (keys are strings).
    	if ( is_array( $current ) && array_is_list( $current ) && array() !== $current ) {
    		_doing_it_wrong(
    			__METHOD__,
    			esc_html__( 'A view configuration patch value must match the shape of the value it patches: a list merges into a list, and an associative array into an associative array.' ),
    			'7.1.0'
    		);
    		return $current;
    	}

    	$result = is_array( $current ) && ! array_is_list( $current ) ? $current : array();
    	foreach ( $incoming as $key => $value ) {
    		// A null patch value deletes the property.
    		if ( null === $value ) {
    			unset( $result[ $key ] );
    			continue;
    		}

    		$result[ $key ] = $this->merge_properties(
    			array_key_exists( $key, $result ) ? $result[ $key ] : array(),
    			$value,
    			$replace_lists
    		);
    	}

    	return $result;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/class-wp-view-config-data.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.1/src/wp-includes/class-wp-view-config-data.php#L515)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.1/src/wp-includes/class-wp-view-config-data.php#L515-L581)

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

| Uses | Description | 
| [WP_View_Config_Data::strip_nulls()](https://developer.wordpress.org/reference/classes/wp_view_config_data/strip_nulls/)`wp-includes/class-wp-view-config-data.php` |

Recursively drops every property whose value is `null` from a value.

  | 
| [WP_View_Config_Data::merge_list_by_identity()](https://developer.wordpress.org/reference/classes/wp_view_config_data/merge_list_by_identity/)`wp-includes/class-wp-view-config-data.php` |

Merges an incoming list into the current one by member identity.

  | 
| [WP_View_Config_Data::merge_properties()](https://developer.wordpress.org/reference/classes/wp_view_config_data/merge_properties/)`wp-includes/class-wp-view-config-data.php` |

Merges an incoming value into the current one, recursing by value shape.

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

Retrieves the translation of $text and escapes it for safe use in HTML output.

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

Marks something as being incorrectly called.

  |

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

| Used by | Description | 
| [WP_View_Config_Data::apply()](https://developer.wordpress.org/reference/classes/wp_view_config_data/apply/)`wp-includes/class-wp-view-config-data.php` |

Applies a patch to the configuration, top-level key by top-level key.

  | 
| [WP_View_Config_Data::merge_properties()](https://developer.wordpress.org/reference/classes/wp_view_config_data/merge_properties/)`wp-includes/class-wp-view-config-data.php` |

Merges an incoming value into the current one, recursing by value shape.

  | 
| [WP_View_Config_Data::merge_list_by_identity()](https://developer.wordpress.org/reference/classes/wp_view_config_data/merge_list_by_identity/)`wp-includes/class-wp-view-config-data.php` |

Merges an incoming list into the current one by member identity.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_view_config_data/merge_properties/?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_view_config_data%2Fmerge_properties%2F)
before being able to contribute a note or feedback.