用 PHP 删除 GET 变量的好方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1251582/
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
Beautiful way to remove GET-variables with PHP?
提问by Jens T?rnell
I have a string with a full URL including GET variables. Which is the best way to remove the GET variables? Is there a nice way to remove just one of them?
我有一个包含 GET 变量的完整 URL 的字符串。删除 GET 变量的最佳方法是什么?有没有一种好方法可以只删除其中一个?
This is a code that works but is not very beautiful (I think):
这是一个有效但不是很漂亮的代码(我认为):
$current_url = explode('?', $current_url);
echo $current_url[0];
The code above just removes all the GET variables. The URL is in my case generated from a CMS so I don't need any information about server variables.
上面的代码只是删除了所有的 GET 变量。就我而言,URL 是从 CMS 生成的,因此我不需要任何有关服务器变量的信息。
回答by Justin
Ok, to remove all variables, maybe the prettiest is
好的,删除所有变量,也许最漂亮的是
$url = strtok($url, '?');
See about strtokhere.
请参阅strtok此处。
Its the fastest (see below), and handles urls without a '?' properly.
它是最快的(见下文),并且处理没有“?”的网址。适当地。
To take a url+querystring and remove just one variable (without using a regex replace, which may be faster in some cases), you might do something like:
要获取 url+querystring 并仅删除一个变量(不使用正则表达式替换,在某些情况下可能会更快),您可以执行以下操作:
function removeqsvar($url, $varname) {
list($urlpart, $qspart) = array_pad(explode('?', $url), 2, '');
parse_str($qspart, $qsvars);
unset($qsvars[$varname]);
$newqs = http_build_query($qsvars);
return $urlpart . '?' . $newqs;
}
A regex replace to remove a single var might look like:
删除单个 var 的正则表达式替换可能如下所示:
function removeqsvar($url, $varname) {
return preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','',$url);
}
Heres the timings of a few different methods, ensuring timing is reset inbetween runs.
这是几种不同方法的计时,确保计时在运行之间重置。
<?php
$number_of_tests = 40000;
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
preg_replace('/\?.*/', '', $str);
}
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo "regexp execution time: ".$totaltime." seconds; ";
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
$str = explode('?', $str);
}
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo "explode execution time: ".$totaltime." seconds; ";
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
$qPos = strpos($str, "?");
$url_without_query_string = substr($str, 0, $qPos);
}
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo "strpos execution time: ".$totaltime." seconds; ";
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
$url_without_query_string = strtok($str, '?');
}
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = ($endtime - $starttime);
echo "tok execution time: ".$totaltime." seconds; ";
shows
显示
regexp execution time: 0.14604902267456 seconds; explode execution time: 0.068033933639526 seconds; strpos execution time: 0.064775943756104 seconds; tok execution time: 0.045819044113159 seconds;
regexp execution time: 0.1408839225769 seconds; explode execution time: 0.06751012802124 seconds; strpos execution time: 0.064877986907959 seconds; tok execution time: 0.047760963439941 seconds;
regexp execution time: 0.14162802696228 seconds; explode execution time: 0.065848112106323 seconds; strpos execution time: 0.064821004867554 seconds; tok execution time: 0.041788101196289 seconds;
regexp execution time: 0.14043688774109 seconds; explode execution time: 0.066350221633911 seconds; strpos execution time: 0.066242933273315 seconds; tok execution time: 0.041517972946167 seconds;
regexp execution time: 0.14228296279907 seconds; explode execution time: 0.06665301322937 seconds; strpos execution time: 0.063700199127197 seconds; tok execution time: 0.041836977005005 seconds;
strtok wins, and is by far the smallest code.
strtok 获胜,并且是迄今为止最小的代码。
回答by Gumbo
How about:
怎么样:
preg_replace('/\?.*/', '', $str)
回答by Matt Bridges
If the URL that you are trying to remove the query string from is the current URL of the PHP script, you can use one of the previously mentioned methods. If you just have a string variable with a URL in it and you want to strip off everything past the '?' you can do:
如果您尝试从中删除查询字符串的 URL 是 PHP 脚本的当前 URL,则可以使用前面提到的方法之一。如果您只有一个带有 URL 的字符串变量,并且您想去掉 '?' 之后的所有内容。你可以做:
$pos = strpos($url, "?");
$url = substr($url, 0, $pos);
回答by COil
Another solution... I find this function more elegant, it will also remove the trailing '?' if the key to remove is the only one in the query string.
另一个解决方案......我发现这个功能更优雅,它还会删除尾随的“?” 如果要删除的键是查询字符串中唯一的键。
/**
* Remove a query string parameter from an URL.
*
* @param string $url
* @param string $varname
*
* @return string
*/
function removeQueryStringParameter($url, $varname)
{
$parsedUrl = parse_url($url);
$query = array();
if (isset($parsedUrl['query'])) {
parse_str($parsedUrl['query'], $query);
unset($query[$varname]);
}
$path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
$query = !empty($query) ? '?'. http_build_query($query) : '';
return $parsedUrl['scheme']. '://'. $parsedUrl['host']. $path. $query;
}
Tests:
测试:
$urls = array(
'http://www.example.com?test=test',
'http://www.example.com?bar=foo&test=test2&foo2=dooh',
'http://www.example.com',
'http://www.example.com?foo=bar',
'http://www.example.com/test/no-empty-path/?foo=bar&test=test5',
'https://www.example.com/test/test.test?test=test6',
);
foreach ($urls as $url) {
echo $url. '<br/>';
echo removeQueryStringParameter($url, 'test'). '<br/><br/>';
}
Will output:
将输出:
http://www.example.com?test=test
http://www.example.com
http://www.example.com?bar=foo&test=test2&foo2=dooh
http://www.example.com?bar=foo&foo2=dooh
http://www.example.com
http://www.example.com
http://www.example.com?foo=bar
http://www.example.com?foo=bar
http://www.example.com/test/no-empty-path/?foo=bar&test=test5
http://www.example.com/test/no-empty-path/?foo=bar
https://www.example.com/test/test.test?test=test6
https://www.example.com/test/test.test
回答by Scharrels
Inspired by the comment of @MitMaro, I wrote a small benchmark to test the speed of solutions of @Gumbo, @Matt Bridges and @justin the proposal in the question:
受到@MitMaro 评论的启发,我写了一个小基准来测试@Gumbo、@Matt Bridges 和@justin 问题中的建议的解决方案的速度:
function teststrtok($number_of_tests){
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
$str = strtok($str,'?');
}
}
function testexplode($number_of_tests){
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
$str = explode('?', $str);
}
}
function testregexp($number_of_tests){
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
preg_replace('/\?.*/', '', $str);
}
}
function teststrpos($number_of_tests){
for($i = 0; $i < $number_of_tests; $i++){
$str = "http://www.example.com?test=test";
$qPos = strpos($str, "?");
$url_without_query_string = substr($str, 0, $qPos);
}
}
$number_of_runs = 10;
for($runs = 0; $runs < $number_of_runs; $runs++){
$number_of_tests = 40000;
$functions = array("strtok", "explode", "regexp", "strpos");
foreach($functions as $func){
$starttime = microtime(true);
call_user_func("test".$func, $number_of_tests);
echo $func.": ". sprintf("%0.2f",microtime(true) - $starttime).";";
}
echo "<br />";
}
strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18; strtok: 0.12;explode: 0.19;regexp: 0.31;strpos: 0.18;
Result: @justin's strtok is the fastest.
结果:@justin 的 strtok 是最快的。
Note: tested on a local Debian Lenny system with Apache2 and PHP5.
注意:在带有 Apache2 和 PHP5 的本地 Debian Lenny 系统上测试。
回答by bobert
Couldn't you use the server variables to do this?
你不能使用服务器变量来做到这一点吗?
Or would this work?:
或者这会起作用吗?:
unset($_GET['page']);
$url = $_SERVER['SCRIPT_NAME'] ."?".http_build_query($_GET);
Just a thought.
只是一个想法。
回答by Rob Haswell
@list($url) = explode("?", $url, 2);
回答by Scharrels
You can use the server variablesfor this, for example $_SERVER['REQUEST_URI'], or even better: $_SERVER['PHP_SELF'].
您可以为此使用服务器变量,例如$_SERVER['REQUEST_URI'],或者甚至更好:$_SERVER['PHP_SELF']。
回答by Question Mark
How about a function to rewrite the query string by looping through the $_GET array
通过循环遍历 $_GET 数组来重写查询字符串的函数如何
! Rough outline of a suitable function
!一个合适函数的粗略轮廓
function query_string_exclude($exclude, $subject = $_GET, $array_prefix=''){
$query_params = array;
foreach($subject as $key=>$var){
if(!in_array($key,$exclude)){
if(is_array($var)){ //recursive call into sub array
$query_params[] = query_string_exclude($exclude, $var, $array_prefix.'['.$key.']');
}else{
$query_params[] = (!empty($array_prefix)?$array_prefix.'['.$key.']':$key).'='.$var;
}
}
}
return implode('&',$query_params);
}
Something like this would be good to keep handy for pagination links etc.
像这样的东西对于分页链接等很方便。
<a href="?p=3&<?= query_string_exclude(array('p')) ?>" title="Click for page 3">Page 3</a>
回答by Sidupac
basename($_SERVER['REQUEST_URI'])returns everything after and including the '?',
basename($_SERVER['REQUEST_URI'])返回包括 '?' 之后的所有内容,
In my code sometimes I need only sections, so separate it out so I can get the value of what I need on the fly. Not sure on the performance speed compared to other methods, but it's really useful for me.
在我的代码中,有时我只需要部分,所以把它分开,这样我就可以即时获得我需要的值。与其他方法相比,不确定性能速度,但它对我来说真的很有用。
$urlprotocol = 'http'; if ($_SERVER["HTTPS"] == "on") {$urlprotocol .= "s";} $urlprotocol .= "://";
$urldomain = $_SERVER["SERVER_NAME"];
$urluri = $_SERVER['REQUEST_URI'];
$urlvars = basename($urluri);
$urlpath = str_replace($urlvars,"",$urluri);
$urlfull = $urlprotocol . $urldomain . $urlpath . $urlvars;

