Manipuler une chaîne d'url en ajoutant des paramètres GET

je veux ajouter les paramètres GET aux URLs qui peuvent et ne peuvent pas contenir les paramètres GET sans répéter ? ou & .

exemple:

si je veux ajouter category=action

$url="http://www.acme.com";
 // will add ?category=action at the end

$url="http://www.acme.com/movies?sort=popular";
 // will add &category=action at the end

si vous remarquez que j'essaie de ne pas répéter le point d'interrogation s'il est trouvé.

L'URL n'est qu'une chaîne de caractères.

Quelle est une façon fiable d'ajouter un paramètre GET spécifique?

62
demandé sur iWillGetBetter 2011-04-27 23:55:53

14 réponses

méthode de base

$query = parse_url($url, PHP_URL_QUERY);

// Returns a string if the URL has parameters or NULL if not
if ($query) {
    $url .= '&category=1';
} else {
    $url .= '?category=1';
}

plus avancé

$url = 'http://example.com/search?keyword=test&category=1&tags[]=fun&tags[]=great';

$url_parts = parse_url($url);
parse_str($url_parts['query'], $params);

$params['category'] = 2;     // Overwrite if exists
$params['tags'][] = 'cool';  // Allows multiple values

// Note that this will url_encode all values
$url_parts['query'] = http_build_query($params);

// If you have pecl_http
echo http_build_url($url_parts);

// If not
echo $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'] . '?' . $url_parts['query'];

vous devriez mettre cela dans une fonction au moins, si pas une classe.

140
répondu andrewtweber 2015-05-12 03:29:11

Voici une version plus courte de la réponse acceptée:

$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action';

modifier: comme discuté dans la réponse acceptée, cela est défectueux en ce qu'il ne vérifie pas si category existe déjà. Une meilleure solution serait de traiter le $_GET pour ce qu'il est - un tableau et utiliser des fonctions comme in_array() .

40
répondu rybo111 2015-09-11 12:49:29
$data = array('foo'=>'bar',
              'baz'=>'boom',
              'cow'=>'milk',
              'php'=>'hypertext processor');

$queryString =  http_build_query($data);
//$queryString = foo=bar&baz=boom&cow=milk&php=hypertext+processor

echo 'http://domain.com?'.$queryString;
//output: http://domain.com?foo=bar&baz=boom&cow=milk&php=hypertext+processor
14
répondu Tom Claus 2011-04-27 20:06:29

Utiliser strpos pour détecter un ?. Depuis ? peut seulement apparaître dans L'URL au début d'une chaîne de requête, vous savez si son là obtenir params existent déjà et vous devez ajouter params en utilisant &

function addGetParamToUrl(&$url, $varName, $value)
{
    // is there already an ?
    if (strpos($url, "?"))
    {
        $url .= "&" . $varName . "=" . $value; 
    }
    else
    {
        $url .= "?" . $varName . "=" . $value;
    }
}
8
répondu Doug T. 2012-08-25 13:11:29

cette fonction remplace un argument existant

function addToURL( $key, $value, $url) {
    $info = parse_url( $url );
    parse_str( $info['query'], $query );
    return $info['scheme'] . '://' . $info['host'] . $info['path'] . '?' . http_build_query( $query ? array_merge( $query, array($key => $value ) ) : array( $key => $value ) );
}
8
répondu user2171027 2013-03-14 17:51:51

exemple avec mise à jour des paramètres existants.

aussi url_encode utilisé, et possibilité de ne pas spécifier la valeur du paramètre

    <?
    /**
     * Add parameter to URL
     * @param string $url
     * @param string $key
     * @param string $value
     * @return string result URL
     */
    function addToUrl($url, $key, $value = null) {
        $query = parse_url($url, PHP_URL_QUERY);
        if ($query) {
            parse_str($query, $queryParams);
            $queryParams[$key] = $value;
            $url = str_replace("?$query", '?' . http_build_query($queryParams), $url);
        } else {
            $url .= '?' . urlencode($key) . '=' . urlencode($value);
        }
        return $url;
    }
6
répondu Артур Курицын 2014-08-17 23:25:56

je pense que vous devriez faire quelque chose comme cela.

class myURL {
    protected $baseURL, $requestParameters;

    public function __construct ($newURL) {
        $this->baseurl = $newURL;
        $this->requestParameters = array();
    }

    public function addParameter ($parameter) {
        $this->requestParameters[] = $parameter;
    }

    public function __toString () {
        return $this->baseurl.
               ( count($this->requestParameters) ?
                 '?'.implode('&', $this->requestParameters) :
                 ''
                 );
    }
}

$url1 = new myURL ('http://www.acme.com');
$url2 = new myURL ('http://www.acme.com');
$url2->addParameter('sort=popular');
$url2->addParameter('category=action');
$url1->addParameter('category=action');

echo $url1."\n".$url2;
3
répondu Hammerite 2011-04-27 20:12:49
<?php
$url1 = '/test?a=4&b=3';
$url2 = 'www.baidu.com/test?a=4&b=3&try_count=1';
$url3 = 'http://www.baidu.com/test?a=4&b=3&try_count=2';
$url4 = '/test';
function add_or_update_params($url,$key,$value){
    $a = parse_url($url);
    $query = $a['query'] ? $a['query'] : '';
    parse_str($query,$params);
    $params[$key] = $value;
    $query = http_build_query($params);
    $result = '';
    if($a['scheme']){
        $result .= $a['scheme'] . ':';
    }
    if($a['host']){
        $result .= '//' . $a['host'];
    }
    if($a['path']){
        $result .=  $a['path'];
    }
    if($query){
        $result .=  '?' . $query;
    }
    return $result;
}
echo add_or_update_params($url1,'try_count',1);
echo "\n";
echo add_or_update_params($url2,'try_count',2);
echo "\n";
echo add_or_update_params($url3,'try_count',3);
echo "\n";
echo add_or_update_params($url4,'try_count',4);
echo "\n";
3
répondu shengbin_xu 2015-11-19 09:20:47
$parameters = array();

foreach ($get as $key => $value)
{
     $parameters[] = $key.'='.$value;
}

$url = 'http://example.com/movies?'.implode('&', $parameters);
2
répondu TaylorOtwell 2011-04-27 19:59:43
 /**
 * @example addParamToUrl('/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
 * @example addParamToUrl('//example.com/path/to/?find=1', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
 * @example addParamToUrl('https://example.com/path/to/?find=1&FILTER=Y', array('find' => array('search', 2), 'FILTER' => 'STATUS'))
 *
 * @param       $url string url
 * @param array $addParams
 *
 * @return string
 */
function addParamToUrl($url, array $addParams) {
  if (!is_array($addParams)) {
    return $url;
  }

  $info = parse_url($url);

  $query = array();

  if ($info['query']) {
    parse_str($info['query'], $query);
  }

  if (!is_array($query)) {
    $query = array();
  }

  $params = array_merge($query, $addParams);

  $result = '';

  if ($info['scheme']) {
    $result .= $info['scheme'] . ':';
  }

  if ($info['host']) {
    $result .= '//' . $info['host'];
  }

  if ($info['path']) {
    $result .= $info['path'];
  }

  if ($params) {
    $result .= '?' . http_build_query($params);
  }

  return $result;
}
2
répondu Londeren 2017-11-29 09:05:22

après avoir cherché de nombreuses ressources/réponses sur ce sujet, j'ai décidé de coder les miennes. Basé sur la réponse de @TaylorOtwell ici, c'est comme ça que je traite la requête $_GET entrante et modifie/manipule chaque élément.

en supposant que l'url est: http://domain.com/category/page.php?a=b&x=y Et je veux qu'un paramètre pour le tri: soit ?desc=column_name ou ?asc=column_name. Ainsi, un seul paramètre d'url suffit pour trier et commander simultanément. Donc L'URL sera http://domain.com/category/page.php?a=b&x=y&desc=column_name sur le premier clic de la ligne d'en-tête de tableau associée.

puis j'ai les titres de ligne de tableau que je veux trier DESC sur mon premier clic, et ASC sur le deuxième clic de la même rubrique. (Chaque premier clic devrait "commander par colonne DESC" en premier) et s'il n'y a pas de tri, il triera par "date puis id" par défaut.

, Vous pouvez l'améliorer, comme vous peut ajouter des fonctions de nettoyage/filtrage à chaque composant $_GET mais la structure ci-dessous pose les fondations.

foreach ($_GET AS $KEY => $VALUE){
    if ($KEY == 'desc'){
        $SORT = $VALUE;
        $ORDER = "ORDER BY $VALUE DESC";
        $URL_ORDER = $URL_ORDER . "&asc=$VALUE";
    } elseif ($KEY == 'asc'){
        $SORT = $VALUE;
        $ORDER = "ORDER BY $VALUE ASC";
        $URL_ORDER = $URL_ORDER . "&desc=$VALUE";
    } else {
        $URL_ORDER .= "&$KEY=$VALUE";
        $URL .= "&$KEY=$VALUE";
    }
}
if (!$ORDER){$ORDER = 'ORDER BY date DESC, id DESC';}
if ($URL_ORDER){$URL_ORDER = $_SERVER[SCRIPT_URL] . '?' . trim($URL_ORDER, '&');}
if ($URL){$URL = $_SERVER[SCRIPT_URL] . '?' . trim($URL, '&');}

(vous pouvez utiliser $_SERVER[SCRIPT_URI] pour L'URL complète commençant par http://domain.com )

puis j'utilise l'ordre $résultant que j'obtiens ci-dessus, dans la requête MySQL:

"SELECT * FROM table WHERE limiter = 'any' $ORDER";

maintenant la fonction pour regarder L'URL s'il y a un tri précédent et ajouter le tri (et l'ordre) paramètre à URL avec"?"ou"&", selon la séquence:

        function sort_order ($_SORT){
            global $SORT, $URL_ORDER, $URL;
            if ($SORT == $_SORT){
                return $URL_ORDER;
            } else {
                if (strpos($URL, '?') !== false){
                    return "$URL&desc=$_SORT";
                } else {                        
                    return "$URL?desc=$_SORT";
                }
            }
        }

enfin, l'en-tête de ligne de table pour utiliser la fonction:

        echo "<th><a href='".sort_order('id')."'>ID</a></th>";

résumé: ceci Lira L'URL, modifiera chacun des $_GET components et fera L'URL finale avec les paramètres de votre choix avec la forme correcte d'usage de "?"et "&"

1
répondu Tarik 2015-09-24 13:30:30

je pense que c'est ce que vous cherchez:

paramètres d'url regex

0
répondu fingerman 2017-05-23 12:03:02
 public function addGetParamToUrl($url, $params)
{
    foreach ($params as $param) {
         if (strpos($url, "?"))
        {
            $url .= "&" .http_build_query($param); 
        }
        else
        {
            $url .= "?" .http_build_query($param); 
        }
    }
    return $url;
}
0
répondu Maor 2017-06-15 09:42:07

une autre version améliorée de la fonction. Mélange de réponses existantes avec de petites améliorations (port support) et corrections de bugs (vérification des clés correctement).

/**
 * @param string $url original url to modify - can be relative, partial etc
 * @param array $paramsOverride associative array, can be empty
 * @return string modified url
 */
protected function overrideUrlQueryParams($url, $paramsOverride){
    if (!is_array($paramsOverride)){
        return $url;
    }

    $url_parts = parse_url($url);

    if (isset($url_parts['query'])) {
        parse_str($url_parts['query'], $params);
    } else {
        $params = [];
    }

    $params = array_merge($params, $paramsOverride);

    $res = '';

    if(isset($url_parts['scheme'])) {
        $res .= $url_parts['scheme'] . ':';
    }

    if(isset($url_parts['host'])) {
        $res .= '//' . $url_parts['host'];
    }

    if(isset($url_parts['port'])) {
        $res .= ':' . $url_parts['port'];
    }

    if (isset($url_parts['path'])) {
        $res .= $url_parts['path'];
    }

    if (count($params) > 0) {
        $res .= '?' . http_build_query($params);
    }

    return $res;
}
0
répondu Roman86 2017-11-28 19:59:04