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?
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.
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()
.
$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
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;
}
}
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 ) );
}
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;
}
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;
<?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";
$parameters = array();
foreach ($get as $key => $value)
{
$parameters[] = $key.'='.$value;
}
$url = 'http://example.com/movies?'.implode('&', $parameters);
/**
* @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;
}
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 "&"
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;
}
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;
}