views:

624

answers:

6

when we add a param to the URL

$redirectURL = $printPageURL . "?mode=1";

it works if $printPageURL is "http://www.somesite.com/print.php", but if $printPageURL is changed in the global file to "http://www.somesite.com/print.php?newUser=1", then the URL becomes badly formed. If the project has 300 files and there are 30 files that append param this way, we need to change all 30 files.

the same if we append using "&mode=1" and $printPageURL changes from "http://www.somesite.com/print.php?new=1" to "http://www.somesite.com/print.php", then the URL is also badly formed.

is there a library in PHP that will automatically handle the "?" and "&", and even checks that existing param exists already and removed that one because it will be replaced by the later one and it is not good if the URL keeps on growing longer?

Update: of the several helpful answers, there seems to be no pre-existing function addParam($url, $newParam) so that we don't need to write it?

+2  A: 

http://www.addedbytes.com/php/querystring-functions/ is a good place to start

EDIT: There's also http://www.php.net/manual/en/class.httpquerystring.php

for example:

$http = new HttpQueryString();
$http->set(array('page' => 1, 'sort' => 'asc')); 
$url = "yourfile.php" . $http->toString();
Jonathan Fingland
is there any standard PHP library? would be surprised if there isn't since PHP is so web programming related.
動靜能量
Please note that `HttpQueryString` is not included in PHP core. It's part of the PECL extension **pecl_http** which must be installed separately (no binary available for Windows).
Stefan Gehrig
+3  A: 

Use this:

http://hu.php.net/manual/en/function.http-build-query.php

WishCow
+5  A: 

Use a combination of parse_url() to explode the URL, parse_str() to explode the query string and http_build_query() to rebuild the querystring. After that you can rebuild the whole url from its original fragments you get from parse_url() and the new query string you built with http_build_query(). As the querystring gets exploded into an associative array (key-value-pairs) modifying the query is as easy as modifying an array in PHP.

EDIT

$query = parse_url('http://www.somesite.com/print.php?mode=1&newUser=1', PHP_URL_QUERY);
// $query = "mode=1&newUser=1"
$params = array();
parse_str($query, $params);
/*
 * $params = array(
 *     'mode'    => '1'
 *     'newUser' => '1'
 * )
 */
unset($params['newUser']);
$params['mode'] = 2;
$params['done'] = 1;
$query = http_build_query($params);
// $query = "mode=2&done=1"
Stefan Gehrig
A: 

using WishCow and sgehrig's suggestion, here is a test:

(assuming no anchor for the URL)

<?php

    echo "<pre>\n";

    function adjustParam($url, $s) {  
     if (preg_match('/(.*?)\?/', $url, $matches)) $urlWithoutParams = $matches[1];
     else $urlWithoutParams = $url; 

     parse_str(parse_url($url, PHP_URL_QUERY), $params);

     if (strpos($s, '=') !== false) {
      list($var, $value) = split('=', $s);
      $params[$var] = urldecode($value);
      return $urlWithoutParams . '?' . http_build_query($params);      
     } else {
      unset($params[$s]);
      $newQueryString = http_build_query($params);
      if ($newQueryString) return $urlWithoutParams . '?' . $newQueryString;      
      else return $urlWithoutParams;
     }

    }

    function addParam($url, $s) {
     return adjustParam($url, $s);
    }

    function delParam($url, $s) {
     return adjustParam($url, $s);    
    }

    echo "trying add:\n";

    echo addParam("http://www.somesite.com/print.php", "mode=3"), "\n";
    echo addParam("http://www.somesite.com/print.php?", "mode=3"), "\n"; 
    echo addParam("http://www.somesite.com/print.php?newUser=1", "mode=3"), "\n";
    echo addParam("http://www.somesite.com/print.php?newUser=1&amp;fee=0", "mode=3"), "\n";
    echo addParam("http://www.somesite.com/print.php?newUser=1&amp;fee=0&amp;", "mode=3"), "\n";
    echo addParam("http://www.somesite.com/print.php?mode=1", "mode=3"), "\n";  

    echo "\n", "now trying delete:\n";

    echo delParam("http://www.somesite.com/print.php?mode=1", "mode"), "\n";   
    echo delParam("http://www.somesite.com/print.php?mode=1&amp;newUser=1", "mode"), "\n";     
    echo delParam("http://www.somesite.com/print.php?mode=1&amp;newUser=1", "newUser"), "\n";   

?>

and the output is:

trying add:
http://www.somesite.com/print.php?mode=3
http://www.somesite.com/print.php?mode=3
http://www.somesite.com/print.php?newUser=1&amp;mode=3
http://www.somesite.com/print.php?newUser=1&amp;fee=0&amp;mode=3
http://www.somesite.com/print.php?newUser=1&amp;fee=0&amp;mode=3
http://www.somesite.com/print.php?mode=3

now trying delete:
http://www.somesite.com/print.php
http://www.somesite.com/print.php?newUser=1
http://www.somesite.com/print.php?mode=1
動靜能量
but there is no pre-existing function call to add or delete param?
動靜能量
I believe there is no built-in function that resolves this problem on strings. You either have to work with arrays and use http_build_query, or roll your own that works on strings.
WishCow
A: 

You can try this:

function removeParamFromUrl($query, $paramToRemove)
{
    $params = parse_url($query);
    if(isset($params['query']))
    {
        $queryParams = array();
        parse_str($params['query'], $queryParams);
        if(isset($queryParams[$paramToRemove])) unset($queryParams[$paramToRemove]);
        $params['query'] = http_build_query($queryParams);
    }
    $ret = $params['scheme'].'://'.$params['host'].$params['path'];
    if(isset($params['query']) && $params['query'] != '' ) $ret .= '?'.$params['query'];
    return $ret;
}
Vlad
forgot to mention, this is for removing query parameters.
Vlad
A: 

None of these solutions work when the url is of the form: xyz.co.uk?param1=2&replace_this_param=2 param1 gets dropped all the time .. which means it never works EVER!

If you look at the code given above:

function addParam($url, $s) {
    return adjustParam($url, $s);
}

function delParam($url, $s) {
    return adjustParam($url, $s);           
}

These functions are IDENTICAL - so how can one add and one delete?!

gez