函数文档

add_query_arg()

💡 云策文档标注

概述

add_query_arg() 函数用于修改 URL 查询字符串,支持通过单个键值对或关联数组添加或移除查询参数。默认返回未转义的字符串,使用时需注意安全转义。

关键要点

  • 函数用于重建 URL 并追加查询变量,有两种调用方式:单个键值对或关联数组。
  • 若省略 URL 参数,则使用当前 URL(基于 $_SERVER['REQUEST_URI'])。
  • 参数值应使用 urlencode() 或 rawurlencode() 适当编码。
  • 将查询变量值设为布尔 false 可移除该键(类似 remove_query_arg())。
  • 返回值默认未转义,输出前必须使用 esc_url() 等进行后期转义,以防止 XSS 攻击。
  • 参数包括:$key(必需,字符串或数组)、$value(可选,字符串)、$url(可选,字符串)。
  • 返回新 URL 查询字符串(未转义)。

代码示例

// 单个键值对方式
add_query_arg( 'key', 'value', 'http://example.com' );

// 关联数组方式
add_query_arg( array(
    'key1' => 'value1',
    'key2' => 'value2',
), 'http://example.com' );

// 使用当前 URL 并添加参数,输出需转义
echo esc_url( add_query_arg( 'foo', 'bar' ) );

// 移除参数并添加新参数
$new_query = add_query_arg( array(
    'foo' => false,
    'baz' => 'qux'
), 'http://example.com/link?foo=bar' );

注意事项

  • 函数自 WordPress 1.5.0 引入,5.3.0 版本正式化参数签名。
  • 在子目录安装 WordPress 时,使用 home_url( add_query_arg( null, null ) ) 可能重复路径,建议使用其他方法获取当前 URL。
  • 某些边缘情况(如值以 == 结尾或包含双引号)可能导致等号被剥离,需注意编码处理。

📄 原文内容

Retrieves a modified URL query string.

Description

You can rebuild the URL and append query variables to the URL query by using this function.
There are two ways to use this function; either a single key and value, or an associative array.

Using a single key and value:

add_query_arg( 'key', 'value', 'http://example.com' );

Using an associative array:

add_query_arg( array(
    'key1' => 'value1',
    'key2' => 'value2',
), 'http://example.com' );

Omitting the URL from either use results in the current URL being used (the value of $_SERVER['REQUEST_URI']).

Values are expected to be encoded appropriately with urlencode() or rawurlencode().

Setting any query variable’s value to boolean false removes the key (see remove_query_arg() ).

Important: The return value of add_query_arg() is not escaped by default. Output should be late-escaped with esc_url() or similar to help prevent vulnerability to cross-site scripting (XSS) attacks.

Parameters

$keystring|arrayrequired
Either a query variable key, or an associative array of query variables.
$valuestringoptional
Either a query variable value, or a URL to act upon.
$urlstringoptional
A URL to act upon.

Return

string New URL query string (unescaped).

More Information

Usage

// Parameters as separate arguments
add_query_arg( $param1, $param2, $old_query_or_uri );

// Parameters as array of key => value pairs
add_query_arg(
array(
'key1' => 'value1',
'key2' => 'value2',
...
),
$old_query_or_uri
);

Source

function add_query_arg( ...$args ) {
	if ( is_array( $args[0] ) ) {
		if ( count( $args ) < 2 || false === $args[1] ) {
			$uri = $_SERVER['REQUEST_URI'];
		} else {
			$uri = $args[1];
		}
	} else {
		if ( count( $args ) < 3 || false === $args[2] ) {
			$uri = $_SERVER['REQUEST_URI'];
		} else {
			$uri = $args[2];
		}
	}

	$frag = strstr( $uri, '#' );
	if ( $frag ) {
		$uri = substr( $uri, 0, -strlen( $frag ) );
	} else {
		$frag = '';
	}

	if ( 0 === stripos( $uri, 'http://' ) ) {
		$protocol = 'http://';
		$uri      = substr( $uri, 7 );
	} elseif ( 0 === stripos( $uri, 'https://' ) ) {
		$protocol = 'https://';
		$uri      = substr( $uri, 8 );
	} else {
		$protocol = '';
	}

	if ( str_contains( $uri, '?' ) ) {
		list( $base, $query ) = explode( '?', $uri, 2 );
		$base                .= '?';
	} elseif ( $protocol || ! str_contains( $uri, '=' ) ) {
		$base  = $uri . '?';
		$query = '';
	} else {
		$base  = '';
		$query = $uri;
	}

	wp_parse_str( $query, $qs );
	$qs = urlencode_deep( $qs ); // This re-URL-encodes things that were already in the query string.
	if ( is_array( $args[0] ) ) {
		foreach ( $args[0] as $k => $v ) {
			$qs[ $k ] = $v;
		}
	} else {
		$qs[ $args[0] ] = $args[1];
	}

	foreach ( $qs as $k => $v ) {
		if ( false === $v ) {
			unset( $qs[ $k ] );
		}
	}

	$ret = build_query( $qs );
	$ret = trim( $ret, '?' );
	$ret = preg_replace( '#=(&|$)#', '$1', $ret );
	$ret = $protocol . $base . $ret . $frag;
	$ret = rtrim( $ret, '?' );
	$ret = str_replace( '?#', '#', $ret );
	return $ret;
}

Changelog

Version Description
5.3.0 Formalized the existing and already documented parameters by adding ...$args to the function signature.
1.5.0 Introduced.

User Contributed Notes

  1. Skip to note 8 content

    Assuming we’re at the WordPress URL “http://blog.example.com/client/?s=word”… Note the use of esc_url() before outputting the link. This is necessary because this function does not escape URLs and if output without escaping, would make the page vulnerable to XSS scripting.

    // This would output '/client/?s=word&foo;=bar'
    echo esc_url( add_query_arg( 'foo', 'bar' ) );
    
    // This would output '/client/?s=word&foo;=bar&baz;=tiny'
    $arr_params = array( 'foo' => 'bar', 'baz' => 'tiny' );
    echo esc_url( add_query_arg( $arr_params ) );

  2. Skip to note 10 content

    Since get_permalink() returns a full URL, you could use that when you want to add variables to a post’s page.

    /*
     * This would output whatever the URL to post ID 9 is, with 'hello=there'
     * appended with either ? or &, depending on what's needed.
     */
    echo esc_url( add_query_arg( 'hello', 'there', get_permalink( 9 ) ) );

  3. Skip to note 11 content

    More often than not you’ll probably find yourself creating URLs using the following method within the page you’re currently on. In these cases you can use the URL you want to affect as the last parameter. The use of esc_url() is not required here, because the value is known to be safe.

    // This would output 'http://blog.example.com/2009/04/16/?hello=world'
    echo esc_url( add_query_arg( 'hello', 'world', 'http://blog.example.com/2009/04/16/' ) );

  4. Skip to note 12 content

    Removing values and setting via an associative array:

    $query = 'http://example.com/link?foo=bar';
    $new_query = add_query_arg( array(
    	'foo' => false,
    	'baz' => 'qux'
    ), $query );
    print( $new_query );
    // <a href="http://example.com/link?baz=qux" rel="nofollow ugc">http://example.com/link?baz=qux</a>

  5. Skip to note 13 content

    If query string value is ending with == one = is stripped out.

    add_query_arg( array( 'something' => 'blabla==' ), 'https://www.google.com' );

    Result will be
    https://www.google.com?something=blabla=
    but should be
    https://www.google.com?something=blabla==

  6. Skip to note 14 content

    A way to get the current total url using add_query_arg

    home_url( add_query_arg( null, null ));