Я хочу добавить параметры 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?
Основной метод
$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';
Изменить: как обсуждалось в принятом ответе, это является недостатком в том, что он не проверяет, существует ли 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 для обнаружения?. Поскольку ? может появляться только в 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; }
<?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);
Я думаю, вы должны сделать это примерно так.
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;
/** * @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 – во втором щелчке того же заголовка. (Каждый первый щелчок должен сначала «ORDER BY column 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-адрес с параметрами по вашему выбору с правильной формой использования «?». а также "&"
Я думаю, что это то, что вы ищете:
регулярные выражения 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; }