Управление строкой url путем добавления параметров GET
Я хочу добавить параметры GET в URL-адреса, которые могут и не могут содержать параметры GET без повторения ?
или &
.
пример:
если я хочу добавить 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
если вы заметили, я пытаюсь не повторять знак вопроса, если он найден.
URL-это просто строка.
что это надежный способ, чтобы добавить конкретные GET-параметр?
14 ответов:
основным методом
$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'; }
более продвинутые
$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'];
вы должны поместить это в функцию, по крайней мере, если не класс.
вот более короткая версия принятого ответа:
$url .= (parse_url($url, PHP_URL_QUERY) ? '&' : '?') . 'category=action';
Edit: как обсуждалось в принятом ответе, это неверно в том, что он не проверяет, если
category
уже существует. Лучшим решением было бы лечить$_GET
для чего это делается - массив и использовать такие функции, как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
использовать strpos для обнаружения a ?. С тех пор ? может отображаться только в URL в начале строки запроса, вы знаете, если его там получить параметры уже существуют, и вам нужно добавить параметры с помощью &
function addGetParamToUrl(&$url, $varName, $value) { // is there already an ? if (strpos($url, "?")) { $url .= "&" . $varName . "=" . $value; } else { $url .= "?" . $varName . "=" . $value; } }
эта функция перезаписывает существующий аргумент
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 ) ); }
пример с обновлением существующих параметров.
также используется url_encode, и возможность не указывать значение параметра
<? /** * 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; }
Я думаю, что вы должны сделать, это что-то вроде этого.
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; }
после поиска многих ресурсов / ответов на эту тему, я решил закодировать свой собственный. Основываясь на ответе @TaylorOtwell здесь, вот как я обрабатываю входящий запрос $_GET и изменяю/манипулирую каждым элементом.
предполагая, что url-адрес:http://domain.com/category/page.php?a=b&x=y И я хочу только один параметр для сортировки: либо ?desc=column_name или ?asc=column_name. Таким образом, одного параметра url достаточно для сортировки и упорядочивания одновременно. Так что URL будет http://domain.com/category/page.php?a=b&x=y&desc=column_name при первом щелчке соответствующей строки заголовка таблицы.
затем у меня есть заголовки строк таблицы, которые я хочу отсортировать DESC при первом щелчке и ASC при втором щелчке того же заголовка. (Каждый первый щелчок должен сначала "упорядочить по столбцу DESC"), и если нет сортировки, он будет сортировать по" дате, то id " по умолчанию.
вы можете улучшить его дальше, как вы можете добавить функции очистки / фильтрации для каждого $ _GET компонент, но ниже структура закладывает основу.
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, '&');}
(вы можете использовать $_SERVER[SCRIPT_URI] для полного URL, начиная с http://domain.com)
затем я использую результирующий $ ORDER, который я получаю выше, в запросе MySQL:
"SELECT * FROM table WHERE limiter = 'any' $ORDER";
теперь функция, чтобы посмотреть на URL, если есть предыдущая сортировка и добавить сортировку (и порядок) параметр URL с "?"или "&" в соответствии с последовательностью:
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"; } } }
наконец, строка таблицы заголовок для использования функции:
echo "<th><a href='".sort_order('id')."'>ID</a></th>";
резюме: это будет читать URL, изменить каждый из компонентов $_GET и сделать окончательный URL с параметрами по вашему выбору с правильной формой использования "?"и "&"
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; }
еще одна улучшенная версия функции. Смешайте существующие ответы с небольшими улучшениями (поддержка портов) и исправлениями (правильная проверка ключей).
/** * @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; }