Beautiful way to remove GET-variables with PHP?
我有一个带有完整URL的字符串,其中包括GET变量。 删除GET变量的最佳方法是哪种? 是否有一种删除其中一个的好方法?
这是一个有效的代码,但不是很漂亮(我认为):
1 2 |
上面的代码仅删除了所有GET变量。 在我的情况下,URL是从CMS生成的,因此我不需要有关服务器变量的任何信息。
好吧,删除所有变量,也许最漂亮的是
1 |
请参阅此处的
它是最快的(请参见下文),并且处理不带"?"的网址正确地。
要采用url + querystring并仅删除一个变量(不使用regex替换,在某些情况下可能会更快),您可以执行以下操作:
1 2 3 4 5 6 7 |
用正则表达式替换删除单个var可能类似于:
1 2 3 | function removeqsvar($url, $varname) { return preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url); } |
以下是几种不同方法的计时,以确保在运行之间重置计时。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <?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;"; |
表演
1 2 3 4 5 | 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获胜,并且是迄今为止最小的代码。
怎么样:
1 |
如果您要从中删除查询字符串的URL是PHP脚本的当前URL,则可以使用前面提到的方法之一。如果您只有一个带有URL的字符串变量,并且想删除所有'?'之后的内容。你可以做:
另一个解决方案...我发现此功能更优雅,它还会删除结尾的"?"如果要删除的键是查询字符串中的唯一键。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * 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; } |
测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $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/>'; } |
将输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
在3v4l上运行这些测试
受@MitMaro的评论启发,我写了一个小型基准测试@ Gumbo,@ Matt Bridges和@justin提案中的解决方案的速度:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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 />"; } |
1 2 3 4 5 6 7 8 9 10 | 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; |
结果:@justin的strtok最快。
注意:已在使用Apache2和PHP5的本地Debian Lenny系统上进行了测试。
您不能使用服务器变量来执行此操作吗?
还是行得通?:
1 2 |
只是一个想法。
您可以为此使用服务器变量,例如
只需使用echo'd javascript以自提交的空白格式删除所有变量的URL:
1 2 3 4 5 | <? if (isset($_GET['your_var'])){ //blah blah blah code echo"<script type='text/javascript'>unsetter();"; ?> |
然后使这个JavaScript函数:
1 2 3 4 | function unsetter() { $('<form id ="unset" name ="unset" METHOD="GET"><input type="submit"></form>').appendTo('body'); $("#unset" ).submit(); } |
我认为,最好的方法是这样的:
它检查是否有'i'GET参数,如果有则将其删除。
有时在我的代码中,我只需要几个部分,因此将其分开,这样我就可以即时获得所需的价值。
不确定与其他方法相比的性能速度,但这对我来说真的很有用。
1 2 3 4 5 6 7 | $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; |
如何通过遍历$ _GET数组重写查询字符串的函数
!合适功能的大致轮廓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); } |
这样的事情对于分页链接等来说很方便。
1 | " title="Click for page 3">Page 3 |