0

I found a bit of code for stripping a query string and adding a new value to it, but I want to be able to do this with an array of options. Could someone give me a hand in modifying this code to do that?

Current code:

function add_querystring_var($url, $key, $value) {
    $url = preg_replace('/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
    $url = substr($url, 0, -1);    
    $value = $value ? "=".urlencode($value) : '';    
    if (strpos($url, '?') === false)
        return ($url . '?' . $key . $value);
    else
        return ($url . '&' . $key . $value);
}

And I want it to do a foreach for each key and value given and then rebuild the new url.

Example: add_querystring_var(curPageURL(), array("order","sort"), array("swn","DESC"))

So I want the following URL http://www.example.com/students when put through the example above would return http://www.example.com/students?order=swn&sort=DESC

Does anyone know how I can do this? I'm new to this area of PHP. :)

UPDATE: I forgot to mention sometimes the url may have other queries in it, so I want it to replace the ones that I enter into my array.

Example 1: http://www.example.com/students?page=2 would need to turn into http://www.example.com/students?page=2&order=swn&sort=DESC

Example 2: http://www.example.com/students?page=2&order=name&sort=ASC would need to turn into http://www.example.com/students?page=2&order=swn&sort=DESC

dpDesignz
  • 1,909
  • 10
  • 34
  • 70

2 Answers2

1
  function add_querystring_var($url, $additions) {
    $parsed = parse_url($url);
    if (isset($parsed['query'])) {
        parse_str($parsed['query'], $query);
    } else {
        $query = array();
    }
    $parsed['query'] = http_build_query(array_merge($query, $additions));
    return http_build_url($parsed);
  }

Use it this way:

$new_url = add_querystring_var($url, array('order' => 'swn', 'sort' => 'DESC'));

If you're getting errors saying that http_build_url is not defined, see

PHP http_build_url() and PECL Install

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks but that didn't work? I just got an error. Should the function have `add_querystring_var($url, &$additions)` not `add_querystring_var($url, $additions)`? But then I get an error `Fatal error: Cannot pass parameter 2 by reference in`. – dpDesignz May 28 '13 at 00:17
  • Why should the additions be a reference parameter? It's not modifying it. I've fixed a problem when the original URL doesn't have a query string. – Barmar May 28 '13 at 00:21
  • I think I've missed something? I'm getting the error `Fatal error: Call to undefined function http_build_url()` – dpDesignz May 28 '13 at 00:25
  • Yeah, I'm getting that too. I thought it was just because I didn't have an optional PECL package installed, so hoped it would work for you. – Barmar May 28 '13 at 00:29
  • thanks but now that's just returning an error `parse_url() expects parameter 1 to be string, array given` from the result – dpDesignz May 28 '13 at 00:38
  • Sorry I think I may actually be confusing you guys by not being very clear with my question. Please see my update. :) – dpDesignz May 28 '13 at 00:43
  • The first argument is supposed to be a string like `"http://www.example.com/students?page=2"`. What array are you giving it? And my code will deal with the original URL having query parameters, that's why it uses `array_merge()`. – Barmar May 28 '13 at 01:10
  • I'm not giving it an array. It's the result of `return http_build_url($parsed);`. Does it replace the query parameters if they already exist? Sorry I still can't get it working for some reason. – dpDesignz May 28 '13 at 01:12
  • How is the return of `http_build_url($parsed)` getting passed to `parse_url()`? `merge_array($parsed['query'], $additions)` merges the additions you give with the original query parameters. If there are any in common, the ones from `$additions` will take precedence (read the documentation). – Barmar May 28 '13 at 01:52
  • I literally copied and pasted your function in. Does it help by knowing that the value of $url in this case is `http://portal.ds/portal/students?sort=asc`? I just realised that I forgot to say that the `parse_url()` that is spitting back the error is the one in the `http_build_url` function, not yours. Thanks. Sorry I just finished looking it up. I hadn't thought to do that before asking you. :) – dpDesignz May 28 '13 at 01:54
  • I just tried it. I'm getting a different error: _Warning: array_merge(): Argument #1 is not an array_. I thought `parse_url()` would parse the query string into an associative array, it doesn't. Back to the drawing board. – Barmar May 28 '13 at 01:58
  • ok I had to fix a couple of things in the `http_build_url` function. Now it's getting down to the build line and spitting back the error `Array to string conversion`. The line in question is `.((isset($parse_url['query'])) ? '?' . $parse_url['query'] : '')` – dpDesignz May 28 '13 at 02:16
  • Did you incorporate the latest changes I made to my code, to call `http_build_query()`? – Barmar May 28 '13 at 02:29
0

You're kind of reinventing the wheel with that function... first off, you'd be better off using urlencode() on your key/value data rather than that regular expression (and I see that you're not encoding your value string at all)

As dpDesignz mentions in his comment - there is a built-in function available: http_build_query()

$querydata = array('foo' => array('bar', 'baz'),
          'baz'=>'boom',
          'cow'=>'milk',
          'php'=>'hypertext processor');

$querystring = http_build_query($data, '', '&');

Or, to use your example:

$querydata = array("order" => "swn", "sort" => "DESC");
$url = curPageURL();
$concat = "?";
if (strpos($url, "?") !== false)) {
    $concat = "&"
}
$url .= $concat . http_build_query($data, '', '&');
HorusKol
  • 8,375
  • 10
  • 51
  • 92
  • thanks for this, but I did forget to mention my url may have other values in it. Please see my update on my question. – dpDesignz May 28 '13 at 00:20
  • Why does it already have values in it? If you're building up the parameters, simply build your query data array and then use `http_build_query()` once at the end - anyway, I've edited my answer to address this caveat – HorusKol May 28 '13 at 00:38
  • Did you see my update? It's pulling my current URL, and replacing certain values from it as required, not all of them. Hope that makes sense. :) – dpDesignz May 28 '13 at 00:40
  • sorry, I missed that - there is probably a better way, still - using $_SERVER['REQUEST_URI'] to get the URI without the querystring, and priming the $querydata array from $_GET first... – HorusKol May 28 '13 at 00:44
  • Thanks yea that's what I though. I've been writing code for hours now and still can't wrap my brain around it. :). – dpDesignz May 28 '13 at 00:55
  • Time to take a break, grab a shower... let your sub-brain think it through while you do something else ;) – HorusKol May 28 '13 at 02:12