WordPress.org

Make WordPress Core

Opened 2 years ago

Closed 2 years ago

#19888 closed enhancement (wontfix)

We need a recursive version of wp_parse_args(), namely wp_parse_args_r()

Reported by: Master Jake Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: General Keywords:
Focuses: Cc:

Description

Currently, wp_parse_args() will merge a collection of possible arguments into a collection of defaults, overriding the defaults when necessary. The issue arises when one of the supplied arguments is an array itself (e.g. an array within an array). Intuitively, one might expect wp_parse_args to treat the inner array as its own instance and merge semi-separately, but it doesn't. We should add this functionality so that users (and possibly the core as well) can start taking advantage of it. It could follow PHP's standard naming convention of suffixing the function name with _r since it's recursive.

An example using wp_parse_args():

$args = array(
        'inner' => array(
                'key1' => 'value1'
        )
);

$defaults = array(
        'rootkey1' => 'rootvalue1',
        'inner' => array(
                'key2' => 'value2',
                'key3' => 'value3'
        )
);

$merged = wp_parse_args( $args, $defaults );

/*
Contents of $merged:

Array
(
        [rootkey1] => rootvalue1
        [inner] => Array
                (
                        [key1] => value1
                )
)

*/

The same example using the new wp_parse_args_r():

$args = array(
        'inner' => array(
                'key1' => 'value1'
        )
);

$defaults = array(
        'rootkey1' => 'rootvalue1',
        'inner' => array(
                'key2' => 'value2',
                'key3' => 'value3'
        )
);

$merged = wp_parse_args( $args, $defaults );

/*
Contents of $merged:

Array
(
        [rootkey1] => rootvalue1
        [inner] => Array
                (
                        [key1] => value1
                        [key2] => value2
                        [key3] => value3
                )
)

*/

Notice the preserved content of the inner array. This new recursive function should perform this way for as many levels down as necessary (hence being a recursive function).

Change History (4)

comment:1 Master Jake2 years ago

  • Type changed from defect (bug) to enhancement

comment:2 nacin2 years ago

I'll bite. I can only think of a single instance in all of core where we nest wp_parse_args() calls, and that would be in WP_Admin_Bar::add_node(), which calls wp_parse_args() not only on $args, but also on $argsmeta?.

Normally, wp_parse_args() is nothing more than an array_merge(). The only reason we have a helper function is because wp_parse_args() transparently handles query string notation ("key=value&key2=value") as well. This works effectively for our functions that take an $args argument, but doesn't translate to a recursive situation. And since we wouldn't have the helper if it weren't for this benefit, I don't see the need for a utility function.

To me, it sounds like any plugin wanting to do a recursive merge of defaults should be doing this on their own, and to their specifications. Given that arguments often store arrays themselves, doing a recursive merge could cause unforeseen problems.

comment:3 Master Jake2 years ago

Ah, I hadn't bothered actually looking at the wp_parse_args implementation yet, but it does make since with the whole "query strings can't be recursive" ordeal.

I thought maybe PHP's array_merge_recursive() function would take care of this, but it seems it has an unexpected result (from a user of wp_parse_arg's perspective) of not overwriting previous keys, but instead creating a new array with the values from the previous and new key and using that array as the new value.

comment:4 scribu2 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

One example of an ambiguous case:

$defaults = array(
  'foo' => 'bar',
  'fruit' => array( 'apple', 'orange' )
);

wp_parse_args_r() would have no way of knowing what to do about 'fruit': treat is a a hash table or as a list of items?

Last edited 2 years ago by scribu (previous) (diff)
Note: See TracTickets for help on using tickets.