php 将查询字符串附加到任何形式的 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5215684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
append query string to any form of URL
提问by I-M-JM
I ask user to input a URL in a text-box and need to append a query string to it.
我要求用户在文本框中输入一个 URL,并需要在其中附加一个查询字符串。
Possible values of URLs can be like:
URL 的可能值可以是:
Now I need to add query string to it like "q2=two", so that output would be like:
现在我需要向它添加查询字符串,如“q2=two”,以便输出如下:
How can I achieve the following using PHP?
如何使用 PHP 实现以下目标?
回答by alex
<?php
$urls = array(
'http://www.example.com',
'http://www.example.com/a/',
'http://www.example.com/a/?q1=one',
'http://www.example.com/a.html',
'http://www.example.com/a.html?q1=one'
);
$query = 'q2=two';
foreach($urls as &$url) {
$parsedUrl = parse_url($url);
if ($parsedUrl['path'] == null) {
$url .= '/';
}
$separator = ($parsedUrl['query'] == NULL) ? '?' : '&';
$url .= $separator . $query;
}
var_dump($urls);
Output
输出
array(5) {
[0]=>
string(29) "http://www.example.com/?q2=two"
[1]=>
string(32) "http://www.example.com/a/?q2=two"
[2]=>
string(39) "http://www.example.com/a/?q1=one&q2=two"
[3]=>
string(36) "http://www.example.com/a.html?q2=two"
[4]=>
&string(43) "http://www.example.com/a.html?q1=one&q2=two"
}
键盘。
回答by Raptor
回答by Don Rhummy
I know this is old, but I improved alex's answerto account for the "#" part of the string.
我知道这很旧,但我改进了亚历克斯的答案以解释字符串的“#”部分。
$urls = array(
'http://www.example.com',
'http://www.example.com/a/#something',
'http://www.example.com/a/?q1=one#soe',
'http://www.example.com/a.html',
'http://www.example.com/a.html?q1=one'
);
$query = 'q2=two';
foreach($urls as &$url) {
$pound = "";
$poundPos = -1;
//Is there a #?
if ( ( $poundPos = strpos( $url, "#" ) ) !== false )
{
$pound = substr( $url, $poundPos );
$url = substr( $url, 0, $poundPos );
}
$separator = (parse_url($url, PHP_URL_QUERY) == NULL) ? '?' : '&';
$url .= $separator . $query . $pound;
}
var_dump($urls);
回答by Deepak Thomas
Enhancing @alex's answer to account for infinite append of query string
增强@alex 的回答以解释查询字符串的无限追加
/* Append QueryString to current URL */
function querystring_append($query) {
$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$parsedUrl = parse_url($url);
if ($parsedUrl['path'] == null) {
$url .= '/';
}
$separator = ($parsedUrl['query'] == NULL) ? '?' : '&';
if(!substr_count($url,$query)) $url .= $separator . $query;
return $url;
}
Usage:
用法:
<?=querystring_append("action=logout") ?>
回答by Ehsan
This is the function I use:
这是我使用的功能:
/**
* @param string $url
* @param $query string|array
* @return string
*/
public function appendQueryStringToURL(string $url, $query): string
{
// the query is empty, return the original url straightaway
if (empty($query)) {
return $url;
}
$parsedUrl = parse_url($url);
if (empty($parsedUrl['path'])) {
$url .= '/';
}
// if the query is array convert it to string
$queryString = is_array($query) ? http_build_query($query) : $query;
// check if there is already any query string in the URL
if (empty($parsedUrl['query'])) {
// remove duplications
parse_str($queryString, $queryStringArray);
$url .= '?' . http_build_query($queryStringArray);
} else {
$queryString = $parsedUrl['query'] . '&' . $queryString;
// remove duplications
parse_str($queryString, $queryStringArray);
// place the updated query in the original query position
$url = substr_replace($url, http_build_query($queryStringArray), strpos($url, $parsedUrl['query']), strlen($parsedUrl['query']));
}
return $url;
}
It accepts query
as string
or array
. Also it handles #
in URL and removes the duplicated query strings automatically. Here is the test as well. Please replace CLASS_THAT_CONTAINS_appendQueryStringToURL
with the correct class
in your project:
它接受query
为string
or array
。它还处理#
URL 并自动删除重复的查询字符串。这里也是测试。请在您的项目中替换CLASS_THAT_CONTAINS_appendQueryStringToURL
为正确class
的:
public function testAppendQueryStringToURL()
{
$helper = new CLASS_THAT_CONTAINS_appendQueryStringToURL();
$inputsOutputs = [
[
'i' => 'http://www.example.com',
'q' => 'q1=1',
'o' => 'http://www.example.com/?q1=1'
],
[
'i' => 'http://www.example.com',
'q' => 'q1=1&q2=2',
'o' => 'http://www.example.com/?q1=1&q2=2'
],
[
'i' => 'http://www.example.com/a/',
'q' => 'q1=1',
'o' => 'http://www.example.com/a/?q1=1'
],
[
'i' => 'http://www.example.com/a.html',
'q' => 'q1=1',
'o' => 'http://www.example.com/a.html?q1=1'
],
[
'i' => 'http://www.example.com/a/?q2=2',
'q' => 'q1=1',
'o' => 'http://www.example.com/a/?q2=2&q1=1'
],
[
'i' => 'http://www.example.com/a.html?q2=two',
'q' => 'q1=1',
'o' => 'http://www.example.com/a.html?q2=two&q1=1'
],
[
'i' => 'http://www.example.com/a.html?q1=1&q2=2',
'q' => 'q1=1',
'o' => 'http://www.example.com/a.html?q1=1&q2=2'
],
// overwrite the existing
[
'i' => 'http://www.example.com/a.html?q1=1&q2=2',
'q' => 'q1=3',
'o' => 'http://www.example.com/a.html?q1=3&q2=2'
],
[
'i' => 'http://www.example.com/a/#something',
'q' => 'q1=1',
'o' => 'http://www.example.com/a/#something?q1=1'
],
[
'i' => 'http://www.example.com/a/?q2=2#soe',
'q' => 'q1=1',
'o' => 'http://www.example.com/a/?q2=2&q1=1#soe'
],
[
'i' => 'http://www.example.com',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/?q1=1'
],
[
'i' => 'http://www.example.com',
'q' => ['q1' => 1, 'q2' => 2],
'o' => 'http://www.example.com/?q1=1&q2=2'
],
[
'i' => 'http://www.example.com/a/',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a/?q1=1'
],
[
'i' => 'http://www.example.com/a.html',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a.html?q1=1'
],
[
'i' => 'http://www.example.com/a/?q2=2',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a/?q2=2&q1=1'
],
[
'i' => 'http://www.example.com/a.html?q2=two',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a.html?q2=two&q1=1'
],
[
'i' => 'http://www.example.com/a.html?q1=1&q2=2',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a.html?q1=1&q2=2'
],
[
'i' => 'http://www.example.com/a.html?q1=1&q2=2',
'q' => ['q1' => 3],
'o' => 'http://www.example.com/a.html?q1=3&q2=2'
],
[
'i' => 'http://www.example.com/a/#something',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a/#something?q1=1'
],
[
'i' => 'http://www.example.com/a/?q2=2#soe',
'q' => ['q1' => 1],
'o' => 'http://www.example.com/a/?q2=2&q1=1#soe'
],
];
foreach ($inputsOutputs as $inputOutput) {
$this->assertEquals($inputOutput['o'], $helper->appendQueryStringToURL($inputOutput['i'], $inputOutput['q']));
}
}
回答by Jacob
If you can install pecl_http then this is a really elegant solution. It can allow you to check if you are overriding a get variable they may have set.
如果您可以安装 pecl_http,那么这是一个非常优雅的解决方案。它可以让您检查是否覆盖了他们可能设置的 get 变量。
$urlComps = parse_url($url);
// Get the current query string
$queryString = isset($urlComps['query']) ? $urlComps['query'] : '';
// Turn it into an array for easy manipulation
parse_str($queryString, $queryVars);
// Make changes to the query vars
$queryVars['q2'] = 'two';
// Empty paths return relative URLs.
$urlComps['path'] = isset($urlComps['path']) ? $urlComps['path'] : '/';
// Make the pecl_http call
$newURL = http_build_url($urlComps, array('query' => http_build_query($queryVars)));
Note: if you can't install pecl_http, the only function that comes from that is the last one with the function http_build_url
. You can fairly easily build your own function to rebuild the URL from its components...
注意:如果你不能安装pecl_http,那么唯一的函数就是最后一个带有函数的函数http_build_url
。您可以相当轻松地构建自己的函数来从其组件重建 URL...
- parse_url
- parse_str
- http_build_query
- http_build_url* uses pecl_http
- 解析网址
- 解析字符串
- http_build_query
- http_build_url* 使用 pecl_http
回答by Tobias Nyholm
This is a bit more tricky that it should be. @alex answer is fine, but it does not support URL fragments nor does it handle duplicate values. I've provided a package for just this scenario. See https://github.com/Nyholm/append_query_string
这应该是有点棘手。@alex 回答很好,但它不支持 URL 片段,也不处理重复值。我已经为这个场景提供了一个包。见https://github.com/Nyholm/append_query_string
$url = 'https://nyholm.tech?example=yes';
$queryString = http_build_query(['foo'=>'bar']);
$result = append_query_string($url, $queryString);
echo $result;
// https://nyholm.tech?example=yes&foo=bar
You may also define how duplicate should be handled. You can decide to:
您还可以定义应如何处理重复项。您可以决定:
- Ignore duplicate values
- Replace
- Skip
- 忽略重复值
- 代替
- 跳过