Quiero agregar parámetros GET a URL que pueden y no pueden contener parámetros GET sin repetir ?
o &
.
Ejemplo:
Si quiero agregar 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 nota que estoy tratando de no repetir el signo de interrogación si lo encuentra.
La URL es solo una cadena.
¿Cuál es una forma confiable de agregar un parámetro GET específico?
echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);
. Pero necesitarápecl install pecl_http
o instalar jakeasmith / http_build_url a través del compositor.Respuestas:
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'; }
Más avanzado
$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'];
Deberías poner esto en una función al menos, si no en una clase.
fuente
?logout
se puede comprobar conisset($_GET["logout"])
echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);
. Pero necesitarápecl install pecl_http
o instalar jakeasmith / http_build_url a través del compositor.Aquí hay una versión más corta de la respuesta aceptada:
$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action';
Editar: como se discutió en la respuesta aceptada, esto es defectuoso porque no verifica si
category
ya existe. Una mejor solución sería tratar el$_GET
por lo que es, una matriz, y usar funciones comoin_array()
.fuente
.
antes de=
.$url
ya tiene 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
fuente
echo http_build_url($url, array("query" => "the=query&parts=here"), HTTP_URL_JOIN_QUERY);
. Pero necesitarápecl install pecl_http
o instalar jakeasmith / http_build_url a través del compositor.Utilice strpos para detectar un?. Ya que ? solo puede aparecer en la URL al comienzo de una cadena de consulta, usted sabe si ya existen parámetros de get y necesita agregar parámetros usando &
function addGetParamToUrl(&$url, $varName, $value) { // is there already an ? if (strpos($url, "?")) { $url .= "&" . $varName . "=" . $value; } else { $url .= "?" . $varName . "=" . $value; } }
fuente
Esta función sobrescribe un 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 ) ); }
fuente
$info['query']
conjunto? No lo has tenido en cuenta.Ejemplo con actualización de parámetros existentes.
También se utilizó url_encode y la posibilidad de no especificar el valor del 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; }
fuente
<?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";
fuente
$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; }
fuente
$parameters = array(); foreach ($get as $key => $value) { $parameters[] = $key.'='.$value; } $url = 'http://example.com/movies?'.implode('&', $parameters);
fuente
Creo que deberías hacer algo como esto.
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;
fuente
Después de buscar muchos recursos / respuestas sobre este tema, decidí codificar el mío. Según la respuesta de @ TaylorOtwell aquí, así es como proceso la solicitud $ _GET entrante y modifico / manipulo cada elemento.
Suponiendo que la URL es: http://domain.com/category/page.php?a=b&x=y Y solo quiero un parámetro para ordenar: ¿? Desc = column_name o? Asc = column_name. De esta manera, un solo parámetro de URL es suficiente para ordenar y ordenar simultáneamente. Entonces, la URL será http://domain.com/category/page.php?a=b&x=y&desc=column_name en el primer clic de la fila de encabezado de la tabla asociada.
Luego tengo encabezados de filas de tabla que quiero ordenar DESC en mi primer clic y ASC en el segundo clic del mismo encabezado. (Cada primer clic debe "ORDER BY COLUMNA DESC" primero) Y si no hay clasificación, se ordenará por "fecha y luego id" de forma predeterminada.
Puede mejorarlo aún más, como si pudiera agregar funciones de limpieza / filtrado a cada componente $ _GET, pero la estructura siguiente sienta las bases.
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, '&');}
(Puede usar $ _SERVER [SCRIPT_URI] para la URL completa que comienza con http://domain.com )
Luego utilizo el $ ORDER resultante que obtengo arriba, en la consulta MySQL:
"SELECT * FROM table WHERE limiter = 'any' $ORDER";
Ahora la función para mirar la URL si hay una clasificación previa y agregar el parámetro de clasificación (y ordenación) a la URL con "?" o "&" según la secuencia:
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, el encabezado de la fila de la tabla para usar la función:
echo "<th><a href='".sort_order('id')."'>ID</a></th>";
Resumen: esto leerá la URL, modificará cada uno de los componentes $ _GET y creará la URL final con los parámetros de su elección con la forma correcta de uso de "?" y "&"
fuente
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; }
fuente
otra versión de función mejorada. Mezcla de respuestas existentes con pequeñas mejoras (compatibilidad con puertos) y correcciones de errores (comprobando las claves correctamente).
/** * @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; }
fuente
Pruebe esta función para agregar parámetros de URL .
Luego, puede deshabilitar el enlace cuando el parámetro está configurado para que no haya un 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>
fuente
En caso de que esté usando WordPress, simplemente puede usar
add_query_args(['sort' => 'asc'], 'http:/example.com/?search=news')
Documentos https://developer.wordpress.org/reference/functions/add_query_arg/
fuente