GET parametreleri ekleyerek bir url dizesini değiştirin


93

?Veya yinelemeden GET parametreleri içerebilen ve içermeyen URL'lere GET parametreleri eklemek istiyorum &.

Misal:

Eklemek istersem 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

Eğer bulunursa soru işaretini tekrar etmemeye çalıştığımı fark ederseniz.

URL yalnızca bir dizedir.

Belirli bir GET parametresini eklemenin güvenilir bir yolu nedir?


Basitçe kullanın: echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);. Ancak composer aracılığıyla jakeasmith / http_build_url'ye ihtiyacınız olacak pecl install pecl_httpveya kuracaksınız .
Ema4rl

Yanıtlar:


188

Temel yöntem

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

Daha ileri

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

Bunu bir sınıf değilse de en azından bir işleve koymalısınız.


2
ayrıca kategori değerini eklemeyi de unutmayın
Doug T.

4
@DougT. tüm parametrelerin bir değere ihtiyacı yoktur. Örneğin,?logoutisset($_GET["logout"])
rybo111

Bu yaklaşım, "kategori" parametresinin zaten URL'de olmadığını bildiğiniz zaman iyidir. Parametre zaten bir URL’de ise, PHP parametrenin URL’deki son oluşumunun değerini almalıdır, böylece @andrewtweber çözümü hala çalışır. Yine de, aşağıdaki stackoverflow.com/a/4101638/99256 çözümünü daha çok beğendim .
Martin Vseticka

Zaten mevcutsa bir parametrenin değiştirilmemesi için -1. Soruda açıkça belirtilmemiştir, ancak mantıksal ve anlamsal olarak zorunludur.
Daniel W.

1
Basitçe kullanın: echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);. Ancak composer aracılığıyla jakeasmith / http_build_url'ye ihtiyacınız olacak pecl install pecl_httpveya kuracaksınız .
Ema4rl

55

İşte kabul edilen cevabın daha kısa bir versiyonu:

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

Düzenleme: Kabul edilen cevapta tartışıldığı gibi, categoryzaten var olup olmadığını kontrol etmemesi nedeniyle bu kusurludur . Daha iyi bir çözüm, $_GETne olduğu için - bir dizi - ve benzeri işlevleri kullanmak olacaktır in_array().


Bunun yalnızca eklenen tek bir parametre ile çalışacağını, aksi takdirde bir? orijinal sorgu yoksa.
Mgamerz

@Mgamerz seni yanlış anlamadıysam, OP'nin istediği buydu. .Öncesinden dolayı birden çok kez çalışır =.
rybo111

Ancak url'ye bir parametre eklerseniz (dolayısıyla bir?) Sorgu olmaz ve tekrar yaparsanız başka bir tane eklerseniz? (İlk satırı tekrar çalıştırmanız gerekmiyorsa)? $ Query nasıl güncellenir?
Mgamerz

@Mgamerz Ne demek istediğini şimdi anladım. Evet, $urlzaten parametrelere sahip olup olmadığını kontrol etmek için her seferinde ilk satırı tekrarlamanız gerekir . Düzenlendi.
rybo111

1
İle URL'leri işlemez #.
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

Basitçe kullanın: echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);. Ancak composer aracılığıyla jakeasmith / http_build_url'ye ihtiyacınız olacak pecl install pecl_httpveya kuracaksınız .
Ema4rl

8

Bir? Algılamak için strpos kullanın . Dan beri ? URL'de yalnızca bir sorgu dizesinin başında görünebilir, bunun zaten var olup olmadığını ve & kullanarak parametreler eklemeniz gerektiğini bilirsiniz.

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

Performans konusunda endişeleriniz varsa iyi ve kolay bir yaklaşım, çünkü bu, parse_url'den çok daha hızlı ve ayrıca daha az cpu yoğunluklu olacaktır. Tradeoff, mevcut bir $ varName'i kontrol etmemesidir.
Dennis Stücken

8

Bu işlev mevcut bir argümanın üzerine yazar

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

$info['query']Set yoksa ne olur ? Bunun hesabını vermedin.
Darren

Ayarlanmazsa, $ info ['sorgu'] NULL olur ve $ sorgu boş bir dizi olur. Yani bu bir sorun değil.
Ajay Singh

7

Mevcut parametreleri güncelleme örneği.

Ayrıca url_encode kullanıldı ve parametre değerini belirtmeme olasılığı

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

3
büyük iş, sadece çizgi yerine $query = $a['query'] ? $a['query'] : '';göre$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

Bence böyle bir şey yapmalısın.

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

Bu konuda birçok kaynak / cevap aradıktan sonra, kendi kodumu yazmaya karar verdim. @ TaylorOtwell'in buradaki cevabına dayanarak, gelen $ _GET talebini bu şekilde işlerim ve her bir öğeyi değiştirir / değiştiririm.

Url'nin şu olduğunu varsayarsak: http://domain.com/category/page.php?a=b&x=y Ve sıralamak için sadece bir parametre istiyorum: ya? Desc = sütun_adı ya da? Asc = sütun_adı. Bu şekilde, tek url parametresi aynı anda sıralamak ve düzenlemek için yeterlidir. Dolayısıyla URL , ilişkili tablo başlığı satırının ilk tıklamasıyla http://domain.com/category/page.php?a=b&x=y&desc=column_name olacaktır .

Ardından, ilk tıklamamda DESC ve aynı başlığın ikinci tıklamasında ASC sıralamak istediğim tablo satırı başlıklarım var. (Her ilk tıklama önce "SİPARİŞ TARAFINDAN SİPARİŞ VER" olmalıdır) Ve eğer sıralama yoksa, varsayılan olarak "tarih sonra id" e göre sıralanır.

Her $ _GET bileşenine temizleme / filtreleme işlevleri ekleyebileceğiniz gibi, ancak aşağıdaki yapı temeli oluşturduğu gibi, onu daha da geliştirebilirsiniz.

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

( Http://domain.com ile başlayan tam URL için $ _SERVER [SCRIPT_URI] kullanabilirsiniz )

Sonra MySQL sorgusunda yukarıda aldığım $ ORDER sonucunu kullanıyorum:

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

Şimdi işlev, önceki bir sıralama varsa URL'ye bakma ve "?" İle URL'ye sıralama (ve sıralama) parametresi ekleme işlevi. veya sıraya göre "&":

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

Son olarak, işlevi kullanmak için tablo satırı başlığı:

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

Özet: Bu, URL'yi okur, $ _GET bileşenlerinin her birini değiştirir ve nihai URL'yi, seçtiğiniz parametrelerle doğru kullanım biçimi "?" İle yapar. ve "&"


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

başka bir geliştirilmiş fonksiyon versiyonu. Küçük iyileştirmeler (bağlantı noktası desteği) ve hata düzeltmeleri (anahtarları düzgün kontrol etme) ile mevcut yanıtların karışımı.

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

URL parametreleri eklemek için bu işlevi deneyin .

Daha sonra, parametre ayarlandığında bağlantıyı devre dışı bırakabilirsiniz, böylece yinelenen url parametresi olmaz.

<?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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.