我有一个带有完整URL的字符串,其中包括GET变量。删除GET变量的最佳方法是哪种?是否有一种删除其中一个的好方法?
这是一个有效的代码,但不是很漂亮(我认为):
$current_url = explode('?', $current_url);
echo $current_url[0];
上面的代码仅删除了所有GET变量。在我的情况下,URL是从CMS生成的,因此我不需要有关服务器变量的任何信息。
我有一个带有完整URL的字符串,其中包括GET变量。删除GET变量的最佳方法是哪种?是否有一种删除其中一个的好方法?
这是一个有效的代码,但不是很漂亮(我认为):
$current_url = explode('?', $current_url);
echo $current_url[0];
上面的代码仅删除了所有GET变量。在我的情况下,URL是从CMS生成的,因此我不需要有关服务器变量的任何信息。
Answers:
好吧,要删除所有变量,也许最漂亮的是
$url = strtok($url, '?');
请看strtok
这里。
它是最快的(请参见下文),并且处理不带“?”的网址 正确地。
要采用url + querystring并仅删除一个变量(不使用regex替换,在某些情况下可能会更快),您可以执行以下操作:
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;
}
用正则表达式替换来删除单个var可能看起来像:
function removeqsvar($url, $varname) {
return preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url);
}
以下是几种不同方法的计时,以确保在运行之间重置计时。
<?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; ";
表演
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获胜,并且是迄今为止最小的代码。
怎么样:
preg_replace('/\\?.*/', '', $str)
如果您要从中删除查询字符串的URL是PHP脚本的当前URL,则可以使用前面提到的方法之一。如果您只有一个带有URL的字符串变量,并且想删除所有'?'之后的内容 你可以做:
$pos = strpos($url, "?");
$url = substr($url, 0, $pos);
?
。然后,您的代码将返回一个空字符串。
$url = ($pos)? substr($url, 0, $pos) : $url;
受@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;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18; strtok:0.12;爆炸:0.19; regexp:0.31; strpos:0.18;
结果:@justin的strtok最快。
注意:在使用Apache2和PHP5的本地Debian Lenny系统上进行了测试。
另一个解决方案...我发现此功能更优雅,它还会删除结尾的“?” 如果要删除的键是查询字符串中的唯一键。
/**
* 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;
}
测试:
$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/>';
}
将输出:
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
如何通过遍历$ _GET数组重写查询字符串的函数
!合适功能的大致轮廓
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);
}
这样的事情对于分页链接等来说很方便。
<a href="?p=3&<?= query_string_exclude(array('p')) ?>" title="Click for page 3">Page 3</a>
basename($_SERVER['REQUEST_URI'])
返回“?”之后的所有内容,包括“?”,
有时在我的代码中,我只需要几个部分,因此将其分开,这样我就可以即时获得所需的价值。不确定与其他方法相比的性能速度,但这对我来说真的很有用。
$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;
我认为最好的方法是这样的:
<? if(isset($_GET['i'])){unset($_GET['i']); header('location:/');} ?>
它检查是否有'i'GET参数,如果有则将其删除。
只需使用echo'd javascript以自提交的空白格式删除所有变量的URL:
<?
if (isset($_GET['your_var'])){
//blah blah blah code
echo "<script type='text/javascript'>unsetter();</script>";
?>
然后使这个JavaScript函数:
function unsetter() {
$('<form id = "unset" name = "unset" METHOD="GET"><input type="submit"></form>').appendTo('body');
$( "#unset" ).submit();
}