wppaste
WordPress

wp_parse_args( string|array|object $args, array $defaults = array() ): array

Since
2.2.0, 2.3.0
Source
wp-includes/functions.php:5012

Combines a set of user supplied arguments with an array of defaults, accepting the input as an array, an object, or a query-string. Falls back to the object's own properties or the parsed string when no non-empty defaults array is supplied, and any keys already present in the input override the matching default. Common companion for shortcode and widget callbacks that need to fill in missing settings.

Merges user defined arguments into defaults array.

Description

This function is used throughout WordPress to allow for both string or array to be merged into another array.

Compatibility

WordPress
since 2.3.0
PHP
7.4–8.6-dev
  • 6.7.7
  • 6.8.8
  • 6.9.7
  • 7.0.4
  • 7.1.0

Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.

Parameters

$argsstring|array|object
Value to merge with $defaults.
$defaultsarrayoptional
Array that serves as the defaults.
Default empty array.Default: array()

Return value

array
Merged user defined values with defaults.

Code examples

Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.

Merge shortcode-style query string arguments into default values

A block of code accepts arguments as a query string and needs sensible defaults for anything the caller omits.

$defaults = array(
	'count' => 5,
	'order' => 'DESC',
);

$args = wp_parse_args( 'count=2&order=ASC', $defaults );

$recent = get_posts( array(
	'numberposts' => $args['count'],
	'order'       => $args['order'],
) );

foreach ( $recent as $recent_post ) {
	echo esc_html( $recent_post->post_title ) . '<br>';
}

The string form is parsed the same way as a URL query string, so keys must be plain ASCII names without spaces.

Fill in missing properties on a settings object

A theme reads customizer-style settings as a stdClass object where some properties may never have been set.

$settings = new stdClass();
$settings->per_page = 3;

$defaults = array(
	'per_page' => 10,
	'layout'   => 'grid',
);

$parsed = wp_parse_args( $settings, $defaults );

printf(
	'Layout: %s, Per page: %d',
	esc_html( $parsed['layout'] ),
	(int) $parsed['per_page']
);

Common problems and fixes · 4

Why does wp_parse_args not apply my defaults array?

The source only merges when $defaults is both an array and non-empty (is_array( $defaults ) && $defaults). Pass an empty array, null, or a truthy non-array value and the function returns $args unchanged, no matter what $args contains.

Why did my numerically indexed array get reindexed after calling wp_parse_args?

- Use string keys for any array you plan to pass through wp_parse_args - For plain numeric lists, merge with the + operator or array_replace() instead

What happens if I pass a raw query string instead of an array?

Anything that is not an array or object falls through to wp_parse_str(), which behaves like PHP's parse_str() and turns 'key=value&key2=value2' into an associative array before the defaults are merged in.

Does wp_parse_args modify the array I passed in?

When $args is already an array, the function assigns $parsed_args by reference to it ($parsed_args =& $args) before merging. The returned value is a new merged array, so the original variable in the caller is not changed by the merge itself.

Alternatives and related functions

shortcode_atts
When you are writing a shortcode callback and want unknown attributes filtered out and a documented filter hook for extending the defaults.
wp_parse_str
When you only need to turn a query string into an array and do not need it merged with a set of defaults.
array_merge
When both inputs are already plain arrays and you do not need object or query-string support.
array_replace
When you need to preserve integer keys exactly as given instead of having them renumbered by the merge.

Performance profile

How much work a call to wp_parse_args() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.

Cost class
Trivial

Touches nothing outside its own arguments.

Scaling
Constant

No loop in the body: the same number of instructions runs whatever you pass in.

Instructions
11–18

Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 26.

Plugin surface
None

Nothing here hands control to plugin code.

Called by
50

50 places in core call this, so the cost is paid more often than your own code shows.

What it touches

  • hookthird-party callbacksapply_filters()one call below wp_parse_args()

What one call costs · 6 distinct outcomes

One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_parse_args() can have, taken from its control-flow graph on PHP 8.5.

WhenInstructionsCalls it makes
!is_object($args) && is_array($args)11–12none
is_object($args)12–13get_object_vars()
!is_object($args) && !is_array($args)13–14wp_parse_str()
!is_object($args) && is_array($args) && is_array($defaults)16array_merge()
is_object($args) && is_array($defaults)17get_object_vars(), array_merge()
!is_object($args) && !is_array($args) && is_array($defaults)18wp_parse_str(), array_merge()

Across PHP versions

Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 26 instructions, 11–18 executed per call, 4 branches. The work does not change between versions.

An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.

Uses · 1

  • wp_parse_str()Parses a string into variables to be stored in an array.

Used by · 50

Show all 50

Source code

function wp_parse_args( $args, $defaults = array() ) {	if ( is_object( $args ) ) {		$parsed_args = get_object_vars( $args );	} elseif ( is_array( $args ) ) {		$parsed_args =& $args;	} else {		wp_parse_str( $args, $parsed_args );	} 	if ( is_array( $defaults ) && $defaults ) {		return array_merge( $defaults, $parsed_args );	}	return $parsed_args;}

Changelog

Introduced in 2.2.0. Unchanged from 6.7.7 through 7.1.0.

  1. 6.7.7
  2. 6.8.8
  3. 6.9.7
  4. 7.0.4
  5. 7.1.0

Signature, return type and hooks compared across 5 parsed releases.

2.3.0
$args can now also be an object.from the docblock
2.2.0
Introduced.from the docblock

About this page

Parsed data
Generated from the wordpress-develop 7.1.0 tag, from src/wp-includes/functions.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.
Corrections
Something wrong on this page? Report it and it gets fixed in the next regeneration.