Как объединить строки запроса в PHP - PullRequest
2 голосов
/ 09 июня 2010

С учетом URL-адреса и строки запроса, как я могу получить URL-адрес, полученный в результате комбинации строки запроса с URL-адресом?

Мне нужна функциональность, аналогичная .htaccess's qsa. Я понимаю, что это было бы довольно просто реализовать полностью вручную, однако есть ли встроенные функции, которые имеют дело со строками запроса, которые могли бы либо упростить, либо полностью решить эту проблему?

Пример набора ввода / результата:

Url="http://www.example.com/index.php/page?a=1"
QS ="?b=2"
Result="http://www.example.com/index.php/page?a=1&b=2"

-

Url="page.php"
QS ="?b=2"
Result="page.php?b=2"

Ответы [ 5 ]

7 голосов
/ 09 июня 2010

Как насчет того, что не использует никаких расширений PECL и не является огромным набором скопированных и вставленных функций?Это немного сложнее, потому что вы объединяете две строки запроса и хотите сделать это не просто $old .= $new;

Мы будем использовать parse_url для извлечениястрока запроса с нужным URL, parse_str для анализа строк запроса, к которым вы хотите присоединиться, array_merge для их объединения и http_build_query для создания нового комбинированногоСтрока для нас.

// Parse the URL into components
$url = 'http://...';
$url_parsed = parse_url($url);
$new_qs_parsed = array();
// Grab our first query string
parse_str($url_parsed['query'], $new_qs_parsed);
// Here's the other query string
$other_query_string = 'that=this&those=these';
$other_qs_parsed = array();
parse_str($other_query_string, $other_qs_parsed);
// Stitch the two query strings together
$final_query_string_array = array_merge($new_qs_parsed, $other_qs_parsed);
$final_query_string = http_build_query($final_query_string_array);
// Now, our final URL:
$new_url = $url_parsed['scheme'] 
         . '://'
         . $url_parsed['host'] 
         . $url_parsed['path'] 
         . '?'      
         . $final_query_string;
1 голос
/ 09 июня 2010

Вы можете получить часть строки запроса из URL, используя:

$_SERVER['QUERY_STRING']

, а затем добавьте его в URL как обычно.

Если вы хотите указать свои собственные переменные в строке запроса, взгляните на:

http_build_query

0 голосов
/ 09 июня 2010

Так что же произойдет, если URL конфликтуют?Если оба URL-адреса содержат компонент b= в строке запроса?Вам нужно будет решить, какая из них влияет.

Вот кусок кода, который делает то, что вы хотите, анализируя каждую строку как URL, затем извлекая часть query url и implode() собирая их вместе.

$url="http://www.example.com/index.php/page?a=1";
$qs ="?b=2";

$url_parsed = parse_url($url);
$qs_parsed = parse_url($qs);

$args = array(
    $url_parsed['query'],
    $qs_parsed['query'],
);

$new_url = $url_parsed['scheme'];
$new_url .= '://';
$new_url .= $url_parsed['host'];
$new_url .= $url_parsed['path'];
$new_url .= '?';
$new_url .= implode('&', $args);

print $new_url;
0 голосов
/ 09 июня 2010

Нет встроенной функции для этого.Однако эту функцию можно использовать из расширения http PECL,

http://usphp.com/manual/en/function.http-build-url.php

Например,

$url = http_build_url("http://www.example.com/index.php/page?a=1",
    array(
        "b" => "2"
    )
);
0 голосов
/ 09 июня 2010

Это серия функций, взятых из «фреймворка» WordPress, которые будут это делать, но это вполне может быть слишком:

add_query_arg ()

/**
 * Retrieve a modified URL query string.
 *
 * You can rebuild the URL and append a new query variable to the URL query by
 * using this function. You can also retrieve the full URL with query data.
 *
 * Adding a single key & value or an associative array. Setting a key value to
 * emptystring removes the key. Omitting oldquery_or_uri uses the $_SERVER
 * value.
 *
 * @since 1.0
 *
 * @param mixed $param1 Either newkey or an associative_array
 * @param mixed $param2 Either newvalue or oldquery or uri
 * @param mixed $param3 Optional. Old query or uri
 * @return string New URL query string.
 */
public function add_query_arg() {
    $ret = '';
    if ( is_array( func_get_arg(0) ) ) {
        $uri = ( @func_num_args() < 2 || false === @func_get_arg( 1 ) ) ? $_SERVER['REQUEST_URI'] : @func_get_arg( 1 );
    } else {
        $uri = ( @func_num_args() < 3 || false === @func_get_arg( 2 ) ) ? $_SERVER['REQUEST_URI'] : @func_get_arg( 2 );
    }

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

    if ( preg_match( '|^https?://|i', $uri, $matches ) ) {
        $protocol = $matches[0];
        $uri = substr( $uri, strlen( $protocol ) );
    } else {
        $protocol = '';
    }

    if ( strpos( $uri, '?' ) !== false ) {
        $parts = explode( '?', $uri, 2 );
        if ( 1 == count( $parts ) ) {
            $base = '?';
            $query = $parts[0];
        } else {
            $base = $parts[0] . '?';
            $query = $parts[1];
        }
    } elseif ( !empty( $protocol ) || strpos( $uri, '=' ) === false ) {
        $base = $uri . '?';
        $query = '';
    } else {
        $base = '';
        $query = $uri;
    }

    parse_str( $query, $qs );

    if ( get_magic_quotes_gpc() )
        $qs = format::stripslashes_deep( $qs );

    $qs = format::urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
    if ( is_array( func_get_arg( 0 ) ) ) {
        $kayvees = func_get_arg( 0 );
        $qs = array_merge( $qs, $kayvees );
    } else {
        $qs[func_get_arg( 0 )] = func_get_arg( 1 );
    }

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

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

stripslashes_deep ()

/**
 * Navigates through an array and removes slashes from the values.
 *
 * If an array is passed, the array_map() function causes a callback to pass the
 * value back to the function. The slashes from this value will removed.
 *
 * @since 1.0
 *
 * @param array|string $value The array or string to be stripped
 * @return array|string Stripped array (or string in the callback).
 */
function stripslashes_deep( $value ) {
    return is_array( $value ) ? array_map( array('self', 'stripslashes_deep'), $value ) : stripslashes( $value );
}

urlencode_deep ()

/**
 * Navigates through an array and encodes the values to be used in a URL.
 *
 * Uses a callback to pass the value of the array back to the function as a
 * string.
 *
 * @since 1.0
 *
 * @param array|string $value The array or string to be encoded.
 * @return array|string $value The encoded array (or string from the callback).
 */
public function urlencode_deep( $value ) {
    return is_array($value) ? array_map( array('self', 'urlencode_deep'), $value) : urlencode($value);
}
...