Bearbeiten Sie eine URL-Zeichenfolge, indem Sie GET-Parameter hinzufügen


91

Ich möchte GET-Parameter zu URLs hinzufügen, die GET-Parameter enthalten können und nicht, ohne ?oder zu wiederholen &.

Beispiel:

Wenn ich hinzufügen möchte 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

Wenn Sie bemerken, dass ich versuche, das Fragezeichen nicht zu wiederholen, wenn es gefunden wurde.

Die URL ist nur eine Zeichenfolge.

Was ist ein zuverlässiger Weg, um einen bestimmten GET-Parameter anzuhängen?


Verwenden Sie einfach : echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);. Sie benötigen pecl install pecl_httpoder installieren jakeasmith / http_build_url über Composer.
Ema4rl

Antworten:


186

Grundlegende Methode

$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';
}

Weiter fortgeschritten

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

$url_parts = parse_url($url);
// If URL doesn't have a query string.
if (isset($url_parts['query'])) { // Avoid 'Undefined index: query'
    parse_str($url_parts['query'], $params);
} else {
    $params = array();
}

$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'];

Sie sollten dies zumindest in eine Funktion einfügen, wenn nicht in eine Klasse.


2
Vergessen Sie auch nicht, den Wert der Kategorie anzuhängen
Doug T.

2
Ich will es ihm nicht zu leicht machen :)
andrewtweber

1
Danke, ich mag auch die Lösung von Doug T. und wünschte, ich könnte mehrere Antworten akzeptieren
Ryan

4
@ DougT. Nicht alle Parameter benötigen einen Wert. Zum Beispiel ?logoutkann mitisset($_GET["logout"])
rybo111

1
Verwenden Sie einfach : echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);. Sie benötigen pecl install pecl_httpoder installieren jakeasmith / http_build_url über Composer.
Ema4rl

52

Hier ist eine kürzere Version der akzeptierten Antwort:

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

Bearbeiten: Wie in der akzeptierten Antwort erläutert, ist dies insofern fehlerhaft, als nicht überprüft wird, ob categorybereits vorhanden. Eine bessere Lösung wäre, das zu behandeln, $_GETwas es ist - ein Array - und Funktionen wie zu verwenden in_array().


Beachten Sie, dass dies nur mit einem einzelnen hinzugefügten Parameter funktioniert, andernfalls wird ein? wenn es keine ursprüngliche Abfrage gab.
Mgamerz

@Mgamerz, es sei denn, ich verstehe dich falsch, das hat das OP verlangt. Es funktioniert mehrmals, wegen der .vor dem =.
Rybo111

Aber keine Abfrage existiert nicht, wenn Sie einen Parameter zur URL hinzufügen (daher ein? Hinzufügen), und wenn Sie es erneut tun, wird ein weiterer hinzugefügt? (Es sei denn, Sie sollten die erste Zeile erneut ausführen)? Wie wird $ query aktualisiert?
Mgamerz

@Mgamerz Ich verstehe was du jetzt meinst. Ja, Sie müssten die erste Zeile jedes Mal wiederholen, um zu überprüfen, ob $urlbereits Parameter vorhanden sind. Bearbeitet.
Rybo111

1
Verarbeitet keine URLs mit #.
NateS

19
$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

Verwenden Sie einfach : echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);. Sie benötigen pecl install pecl_httpoder installieren jakeasmith / http_build_url über Composer.
Ema4rl

8

Verwenden Sie strpos , um ein? Zu erkennen. Schon seit ? kann nur in der URL am Anfang einer Abfragezeichenfolge angezeigt werden. Sie wissen, ob dort bereits Abrufparameter vorhanden sind, und Sie müssen Parameter mit & hinzufügen

function addGetParamToUrl(&$url, $varName, $value)
{
    // is there already an ?
    if (strpos($url, "?"))
    {
        $url .= "&" . $varName . "=" . $value; 
    }
    else
    {
        $url .= "?" . $varName . "=" . $value;
    }
}

Guter und einfacher Ansatz, wenn Sie sich Gedanken über die Leistung machen, da dies viel schneller als parse_url und auch weniger CPU-intensiv ist. Der Nachteil ist, dass nicht nach einem vorhandenen $ varName gesucht wird.
Dennis Stücken

8

Diese Funktion überschreibt ein vorhandenes Argument

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 ) );
}

Was passiert, wenn kein $info['query']Set vorhanden ist? Das hast du nicht berücksichtigt.
Darren

Wenn nicht festgelegt, wird $ info ['query'] zu NULL und $ query zu einem leeren Array. Es ist also kein Problem.
Ajay Singh

7

Beispiel mit Aktualisierung vorhandener Parameter.

Es wird auch url_encode verwendet und die Möglichkeit, keinen Parameterwert anzugeben

    <?
    /**
     * 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;
    }

5
<?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";

Ich mag das! Ich gehe auf diese :)
Paolo Falomo

3
tolle Arbeit, ersetzen Sie nur die Zeile $query = $a['query'] ? $a['query'] : '';durch$query = isset($a['query']) ? $a['query'] : '';
emmgfx

4
 /**
 * @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;
}

3
$parameters = array();

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

$url = 'http://example.com/movies?'.implode('&', $parameters);

3

Ich denke, du solltest es so machen.

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;

1

Nachdem ich nach vielen Ressourcen / Antworten zu diesem Thema gesucht hatte, entschied ich mich, meine eigenen zu codieren. Basierend auf der Antwort von @ TaylorOtwell hier verarbeite ich auf diese Weise eingehende $ _GET-Anforderungen und ändere / manipuliere jedes Element.

Angenommen, die URL lautet: http://domain.com/category/page.php?a=b&x=y Und ich möchte nur einen Parameter zum Sortieren: entweder? Desc = Spaltenname oder? Asc = Spaltenname. Auf diese Weise reicht ein einziger URL-Parameter aus, um gleichzeitig zu sortieren und zu bestellen. Die URL lautet also http://domain.com/category/page.php?a=b&x=y&desc=column_name, wenn Sie zum ersten Mal auf die zugehörige Tabellenkopfzeile klicken.

Dann habe ich Tabellenzeilenüberschriften, die ich beim ersten Klick nach DESC und beim zweiten Klick nach ASC sortieren möchte. (Jeder erste Klick sollte zuerst "ORDER BY column DESC" sein.) Wenn keine Sortierung erfolgt, wird standardmäßig nach "date then id" sortiert.

Sie können es weiter verbessern, indem Sie jeder $ _GET-Komponente Reinigungs- / Filterfunktionen hinzufügen, aber die folgende Struktur legt den Grundstein.

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, '&');}

(Sie können $ _SERVER [SCRIPT_URI] für eine vollständige URL verwenden, die mit http://domain.com beginnt. )

Dann verwende ich den resultierenden $ ORDER, den ich oben in der MySQL-Abfrage erhalte:

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

Nun die Funktion, die URL zu überprüfen, wenn es eine vorherige Sortierung gibt, und der URL einen Sortier- (und Ordnungs-) Parameter mit "?" oder "&" entsprechend der Reihenfolge:

        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";
                }
            }
        }

Schließlich der Tabellenzeilenkopf, um die Funktion zu verwenden:

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

Zusammenfassung: Hiermit wird die URL gelesen, jede der $ _GET-Komponenten geändert und die endgültige URL mit Parametern Ihrer Wahl mit der korrekten Verwendungsform von "?" und "&"


0
 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

eine weitere verbesserte Funktionsversion. Mischung aus vorhandenen Antworten mit kleinen Verbesserungen (Port-Unterstützung) und Bugfixes (ordnungsgemäße Überprüfung der Schlüssel).

/**
 * @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

Versuchen Sie diese Funktion, um URL-Parameter hinzuzufügen .

Anschließend können Sie den Link deaktivieren, wenn der Parameter so eingestellt ist, dass kein Duplikat des URL-Parameters vorhanden ist.

<?php
  function addQueryString($a)
                {
             if (empty($_SERVER['QUERY_STRING']))
               return '?' . $a;
             else if (!empty($_SERVER['QUERY_STRING']))
              return '?' . $_SERVER['QUERY_STRING'] . '&' . $a;
                }
?>

 <a href="<?php echo addQueryString('lang=en'); ?>">test</a>
 <a href="<?php echo addQueryString('category=5'); ?>">sat</a>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.