【问题标题】:better way to replace query string value in a given url替换给定 url 中的查询字符串值的更好方法
【发布时间】:2011-09-09 02:30:54
【问题描述】:

好的.. 所以基本上,假设我们有一个链接:

$url = "http://www.site.com/index.php?sub=Mawson&state=QLD&cat=4&page=2&sort=z";

基本上,我需要创建一个函数,替换URL中的每一个东西,例如:

<a href="<?=$url;?>?sort=a">Sort by A-Z</a>
<a href="<?=$url;?>?sort=z">Sort by Z-A</a>

或者,再举一个例子:

<a href="<?=$url;?>?cat=1">Category 1</a>
<a href="<?=$url;?>?cat=2">Category 2</a>

或者,另一个例子:

<a href="<?=$url;?>?page=1">1</a>
<a href="<?=$url;?>?page=2">2</a>
<a href="<?=$url;?>?page=3">3</a>
<a href="<?=$url;?>?page=4">4</a>

所以基本上,我们需要一个函数来替换 URL 中的特定 $_GET,这样我们就不会得到重复,例如:?page=2&amp;page=3

话虽如此,它需要聪明,所以它知道参数的开头是?还是&amp;

我们还需要它是智能的,这样我们才能拥有这样的 URL:

<a href="<?=$url;?>page=3">3</a> (without the ? - so it will detect automatically wether to use an `&` or a `?`

我不介意为某些 $_GET 参数为每​​个 preg_replace 制作不同的变量,但我正在寻找最好的方法。

谢谢。

【问题讨论】:

标签: php query-string


【解决方案1】:

这样的事情怎么样?

function merge_querystring($url = null,$query = null,$recursive = false)
{
  // $url = 'http://www.google.com.au?q=apple&type=keyword';
  // $query = '?q=banana';
  // if there's a URL missing or no query string, return
  if($url == null)
    return false;
  if($query == null)
    return $url;
  // split the url into it's components
  $url_components = parse_url($url);
  // if we have the query string but no query on the original url
  // just return the URL + query string
  if(empty($url_components['query']))
    return $url.'?'.ltrim($query,'?');
  // turn the url's query string into an array
  parse_str($url_components['query'],$original_query_string);
  // turn the query string into an array
  parse_str(parse_url($query,PHP_URL_QUERY),$merged_query_string);
  // merge the query string
  if($recursive == true)
    $merged_result = array_merge_recursive($original_query_string,$merged_query_string);
  else
    $merged_result = array_merge($original_query_string,$merged_query_string);
  // Find the original query string in the URL and replace it with the new one
  return str_replace($url_components['query'],http_build_query($merged_result),$url);
}

用法...

<a href="<?=merge_querystring($url,'?page=1');?>">Page 1</a>
<a href="<?=merge_querystring($url,'?page=2');?>">Page 2</a>

【讨论】:

  • 很简单,就是把URL末尾的查询字符串参数变成一个数组,然后把第二个参数变成一个数组,合并两个数组(这样第二组就覆盖了第一个set) 然后将数组转换回查询字符串,然后查找原始查询字符串并将其替换为新编译的字符串。我没有编码的是,如果初始 URL 值上没有查询字符串,此时我可以使函数只附加新的查询字符串。
  • 我们如何使它工作,如果没有任何 $_GET 参数,它仍然可以工作?例如:site.com/index.php,然后是为site.com/index.php?sort=a 创建的链接(就像我目前这样做的时候,如果没有 $_GET,则不会添加 sort=a。
  • 我已经接受了你的回答,但是在没有任何 $_GET 参数的情况下让它工作是完美的。
  • 我会尝试稍微清理一下该函数并使其更具可读性。但如果不需要合并,它现在应该只做一个简单的字符串 concat
  • +1 在这里也可以完美运行。合并查询字符串值或添加查询字符串(如果不存在)。
【解决方案2】:

嗯,我有同样的问题,找到了这个问题,最后,我更喜欢我自己的方法。也许它有缺陷,那么请告诉我它们是什么。 我的解决方案是:

$query=$_GET;
$query['YOUR_NAME']=$YOUR_VAL;
$url=$_SERVER['PHP_SELF']. '?' .  http_build_query($query);

希望对你有帮助。

【讨论】:

    【解决方案3】:
    <?php
    function change_query ( $url , $array ) {
        $url_decomposition = parse_url ($url);
        $cut_url = explode('?', $url);
        $queries = array_key_exists('query',$url_decomposition)?$url_decomposition['query']:false;
        $queries_array = array ();
        if ($queries) {
            $cut_queries   = explode('&', $queries);
            foreach ($cut_queries as $k => $v) {
                if ($v)
                {
                    $tmp = explode('=', $v);
                    if (sizeof($tmp ) < 2) $tmp[1] = true;
                    $queries_array[$tmp[0]] = urldecode($tmp[1]);
                }
            }
        }
        $newQueries = array_merge($queries_array,$array);
        return $cut_url[0].'?'.http_build_query($newQueries);
    }
    ?>
    

    这样使用:

    <?php
        echo change_query($myUrl, array('queryKey'=>'queryValue'));
    ?>
    

    我今天早上这样做,它似乎在所有情况下都有效。您可以使用数组更改/添加多个查询;)

    【讨论】:

    • 如果有人需要删除没有值的参数,只需检查$tmp[1]是否不为空然后设置$querues_array
    【解决方案4】:
    function replaceQueryParams($url, $params)
    {
        $query = parse_url($url, PHP_URL_QUERY);
        parse_str($query, $oldParams);
    
        if (empty($oldParams)) {
            return rtrim($url, '?') . '?' . http_build_query($params);
        }
    
        $params = array_merge($oldParams, $params);
    
        return preg_replace('#\?.*#', '?' . http_build_query($params), $url);
    }
    

    $url 例子:

    $params 示例:

    [
       'foo' => 'not-bar',
    ]
    

    注意:它不理解带有锚点(哈希)的 URL,例如 http://example.com/page?foo=bar#section1

    【讨论】:

      【解决方案5】:

      如果我没看错的话,我可能不是。您知道要在 url 字符串中替换哪个 GET 吗?这可能很草率,但是...

      $url_pieces = explode( '?', $url );
      $var_string = $url_pieces[1].'&';
      $new_url = $url_pieces[0].preg_replace( '/varName\=value/', 'newVarName=newValue', $var_string );
      

      这是我的看法,祝你好运。

      【讨论】:

        【解决方案6】:

        我不知道这是否是你想要完成的,但无论如何它都在这里:

        <?php
            function mergeMe($url, $assign) {
                list($var,$val) = explode("=",$assign);
                //there's no var defined
                if(!strpos($url,"?")) {
                    $res = "$url?$assign";
                } else {
                    list($base,$vars) = explode("?",$url);
                    //if the vars dont include the one given
                    if(!strpos($vars,$var)) {
                        $res = "$url&$assign";
                    } else {
                        $res = preg_replace("/$var=[a-zA-Z0-9_]*(&|$)/",$assign."&",$url);
                        $res = preg_replace("/&$/","",$res); //remove possible & at the end
                    }
                }
                //just to show the difference, should be "return $res;" instead
                return "$url <strong>($assign)</strong><br>$res<hr>";
            }
        
            //example
            $url1 = "http://example.com";
            $url2 = "http://example.com?sort=a";
            $url3 = "http://example.com?sort=a&page=0";
            $url4 = "http://example.com?sort=a&page=0&more=no";
        
            echo mergeMe($url1,"page=4");
            echo mergeMe($url2,"page=4");
            echo mergeMe($url3,"page=4");
            echo mergeMe($url4,"page=4");
        ?>
        

        【讨论】:

        • 嘿,笨蛋,我认为这会很慢,因为您在这里使用 preg_replace 2x
        【解决方案7】:

        改进 Scuzzy 2013 功能 干净的 url 查询字符串的最后部分。

        // merge the query string
        // array_filter removes empty query array
            if ($recursive == true) {
                $merged_result = array_filter(array_merge_recursive($original_query_string, $merged_query_string));
            } else {
                $merged_result = array_filter(array_merge($original_query_string, $merged_query_string));
            }
        
            // Find the original query string in the URL and replace it with the new one
            $new_url = str_replace($url_components['query'], http_build_query($merged_result), $url);
        
            // If the last query string removed then remove ? from url 
            if(substr($new_url, -1) == '?') {
               return rtrim($new_url,'?');
            }
            return $new_url;
        

        【讨论】:

          【解决方案8】:
          <?php
          //current url: http://localhost/arters?sub=Mawson&state=QLD&cat=4&page=2&sort=a
          
          function change_query($queryKey, $queryValue){
              $queryStr = $_SERVER['QUERY_STRING'];
              parse_str($queryStr, $output);
              $output[$queryKey] = $queryValue;
              return http_build_query($output);
          }
          

          用法:

          <a href="?<?=change_query("sort",'z');?>">sort by z</a>
          

          //http://localhost/arters?sub=Mawson&state=QLD&cat=4&page=2&sort=z

          <a href="?<?=change_query("page",'5');?>">Page 5</a>
          

          //http://localhost/arters?sub=Mawson&state=QLD&cat=4&page=5&sort=a

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-10-07
            • 2023-03-13
            • 1970-01-01
            • 2012-02-15
            • 1970-01-01
            • 2011-09-25
            • 2010-10-17
            • 1970-01-01
            相关资源
            最近更新 更多