我有一个完整的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生成的,所以我并不需要对服务器变量的任何信息,我的情况。
好了,除去所有的变量,也许最漂亮的是
$url = strtok($url, '?');
请参阅有关strtok
在这里 。
它最快的(见下文),并处理的网址没有一个“?” 正常。
举一个URL查询字符串+和删除只有一个变量(不使用正则表达式替换,这可能是在某些情况下更快),你可以这样做:
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;
}
一个正则表达式替换删除一个变种可能看起来像:
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字符串变量,你想去掉一切都会过去的“?” 你可以做:
$pos = strpos($url, "?");
$url = substr($url, 0, $pos);
通过@MitMaro的评论启发,我写了一个小的基准测试@Gumbo,@马特桥梁和@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;
结果:// @ Justin的strtok的是最快的。
注:本地Debian的莱尼系统的Apache2和PHP5进行测试。
另一种解决方案...我发现这个功能更优雅,它也将删除尾随“?” 如果键删除是在查询字符串中唯一的一个。
/**
* 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
»运行在3v4l这些测试
你不能使用服务器变量来做到这一点?
或者将这项工作?:
unset($_GET['page']);
$url = $_SERVER['SCRIPT_NAME'] ."?".http_build_query($_GET);
只是一个想法。
您可以使用服务器变量对于这一点,例如$_SERVER['REQUEST_URI']
甚至更好: $_SERVER['PHP_SELF']
怎么样功能通过$ _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>
@list($url) = explode("?", $url, 2);
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参数,并删除它是否存在。