Desejo adicionar parâmetros GET a URLs que podem ou não conter parâmetros GET sem repetir ?
ou &
.
Exemplo:
Se eu quiser adicionar 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
Se você perceber que estou tentando não repetir o ponto de interrogação, se ele for encontrado.
O URL é apenas uma string.
Qual é uma maneira confiável de anexar um parâmetro GET específico?
echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);
. Mas você precisarápecl install pecl_http
instalar jakeasmith / http_build_url via composer.Respostas:
Método básico
$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'; }
Mais avancado
$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'];
Você deve colocar isso em uma função, pelo menos, se não em uma classe.
fonte
?logout
pode ser verificado comisset($_GET["logout"])
echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);
. Mas você precisarápecl install pecl_http
instalar ou instalar jakeasmith / http_build_url via composer.Esta é uma versão mais curta da resposta aceita:
$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action';
Editar: conforme discutido na resposta aceita, isso é errado porque não verifica se
category
já existe. Uma solução melhor seria tratar o$_GET
pelo que ele é - um array - e usar funções comoin_array()
.fonte
.
antes do=
.$url
já possui parâmetros. Editado.#
.$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
fonte
echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);
. Mas você precisarápecl install pecl_http
instalar ou instalar jakeasmith / http_build_url via composer.Use strpos para detectar um?. Desde a ? só pode aparecer no URL no início de uma string de consulta, você sabe se já existe get params e você precisa adicionar params usando &
function addGetParamToUrl(&$url, $varName, $value) { // is there already an ? if (strpos($url, "?")) { $url .= "&" . $varName . "=" . $value; } else { $url .= "?" . $varName . "=" . $value; } }
fonte
$url .= (strpos($url, '?') === false ? '?' : '&').'category=action';
E em termos de desempenho, seria melhor usar aspas simples. Fora isso, essa solução se ajusta melhor aos requisitos.Esta função substitui um argumento existente
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 ) ); }
fonte
$info['query']
conjunto? Você não contabilizou isso.Exemplo de atualização de parâmetros existentes.
Também url_encode usado e possibilidade de não especificar o valor do parâmetro
<? /** * 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; }
fonte
<?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";
fonte
$query = $a['query'] ? $a['query'] : '';
por$query = isset($a['query']) ? $a['query'] : '';
/** * @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; }
fonte
$parameters = array(); foreach ($get as $key => $value) { $parameters[] = $key.'='.$value; } $url = 'http://example.com/movies?'.implode('&', $parameters);
fonte
Eu acho que você deveria fazer algo assim.
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;
fonte
Depois de pesquisar muitos recursos / respostas sobre este tópico, decidi codificar o meu próprio. Com base na resposta de @TaylorOtwell aqui, é assim que processo a solicitação $ _GET de entrada e modifico / manipulo cada elemento.
Supondo que o url seja: http://domain.com/category/page.php?a=b&x=y E eu quero apenas um parâmetro para classificação:? Desc = column_name ou? Asc = column_name. Dessa forma, um único parâmetro de url é suficiente para classificar e ordenar simultaneamente. Portanto, o URL será http://domain.com/category/page.php?a=b&x=y&desc=column_name no primeiro clique da linha de cabeçalho da tabela associada.
Então, tenho cabeçalhos de linha de tabela que desejo classificar DESC no meu primeiro clique e ASC no segundo clique do mesmo cabeçalho. (Cada primeiro clique deve "ORDER BY coluna DESC" primeiro) E se não houver classificação, ele será classificado por "data e id" por padrão.
Você pode melhorá-lo ainda mais, como pode adicionar funções de limpeza / filtragem a cada componente $ _GET, mas a estrutura abaixo estabelece a base.
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, '&');}
(Você pode usar $ _SERVER [SCRIPT_URI] para URL completo começando com http://domain.com )
Então eu uso $ ORDER resultante obtido acima, na consulta MySQL:
"SELECT * FROM table WHERE limiter = 'any' $ORDER";
Agora a função de olhar para a URL se houver uma classificação anterior e adicionar o parâmetro de classificação (e ordenação) à URL com "?" ou "&" de acordo com a sequência:
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"; } } }
Finalmente, o cabeçalho da linha da tabela para usar a função:
echo "<th><a href='".sort_order('id')."'>ID</a></th>";
Resumo: isso irá ler a URL, modificar cada um dos componentes $ _GET e fazer a URL final com parâmetros de sua escolha com a forma correta de uso de "?" e "&"
fonte
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; }
fonte
outra versão de função aprimorada. Mistura de respostas existentes com pequenas melhorias (suporte de porta) e correções de bugs (verificar as chaves corretamente).
/** * @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; }
fonte
Experimente esta função para adicionar parâmetros de URL .
Em seguida, você pode desativar o link quando o parâmetro é definido para que não haja parâmetro de url duplicado.
<?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>
fonte
Caso você esteja usando WordPress, você pode simplesmente usar
add_query_args(['sort' => 'asc'], 'http:/example.com/?search=news')
Docs https://developer.wordpress.org/reference/functions/add_query_arg/
fonte