使用PHP从给定URL中删除GET参数的最佳方法
很长一段时间以来,我一直在使用以下函数删除get参数:使用PHP从给定URL中删除GET参数的最佳方法,php,regex,url,get,Php,Regex,Url,Get,很长一段时间以来,我一直在使用以下函数删除get参数: function removeGetParameter($url, $varname) { return preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url); } (摘自) 但是我注意到,如果我删除所有参数,我会在字符串的末尾得到一个问号后缀?。如果在字符串末尾找到?,我不能只修剪掉它,因为它可能是另一个GET参数的值(即http://exam
function removeGetParameter($url, $varname) {
return preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url);
}
(摘自)
但是我注意到,如果我删除所有参数,我会在字符串的末尾得到一个问号后缀?
。如果在字符串末尾找到?
,我不能只修剪掉它,因为它可能是另一个GET参数的值(即http://example.com?myquestion=are+你在这里+吗?
)
我提出了这个解决方案,但我怀疑它的效率
function removeGetParameter($url, $varname) {
$p = parse_url($url);
parse_str($p['query'], $vars);
unset($vars[$varname]);
$vars_str = (count($vars) ? '?':'').http_build_query($vars);
return $p['scheme'].'://'.$p['host'].$vars_str;
}
它完成了任务,但我相信它比许多其他选择都慢
是否有任何通用的、安全的方法可以从给定的URL中删除特定的GET参数
谢谢
编辑:我添加了
如果
条件更安全(我们可能根本没有变量)
这是最佳解决方案吗?你说得对。regex版本更快,即使有另一个包装器regex来处理恼人的问题?最后:
<?php
set_time_limit(0);
$url = 'http://google.com/?teste=waldson&name=patricio';
function removeGetParameter($url, $varname) {
return preg_replace('#\\?$#', '', preg_replace('/([?&])'.$varname.'=[^&]+(&|$)/','$1',$url));
}
function removeGetParameter2($url, $varname) {
$p = parse_url($url);
parse_str($p['query'], $vars);
unset($vars[$varname]);
$vars_str = (count($vars) ? '?':'').http_build_query($vars);
return $p['scheme'].'://'.$p['host'].$vars_str;
}
$startTime = microtime(TRUE);
for ($i = 0; $i < 300000; ++$i) {
removeGetParameter($url, 'teste');
removeGetParameter($url, 'name');
}
$totalTime = microtime(true) - $startTime;
$startTime2 = microtime(TRUE);
for ($i = 0; $i < 300000; ++$i) {
removeGetParameter2($url, 'teste');
removeGetParameter2($url, 'name');
}
$totalTime2 = microtime(true) - $startTime2;
echo 'Time regex: ' . $totalTime . '<br />';
echo 'Time parse_url: ' . $totalTime2;
您的
removeGetParameter
的这个修改版本应该可以完成这项工作。好的,我的最终代码:
function removeGetParameter($url, $varname) {
$p = parse_url($url); // parse the url to parts.
parse_str($p['query'] ?? '', $vars); // make an array of the parameters if exist ($vars)
unset($vars[$varname]); // unset the unwanted
$vars_str = http_build_query($vars); // build the query string
return unparse_url($p, $vars_str);
}
function unparse_url($p, $custom_query = NULL) {
// my customization to http://php.net/manual/en/function.parse-url.php thomas at gielfeldt dot com
$scheme = isset($p['scheme']) ? $p['scheme'] . '://' : '';
$host = isset($p['host']) ? $p['host'] : '';
$port = isset($p['port']) ? ':' . $p['port'] : '';
$user = isset($p['user']) ? $p['user'] : '';
$pass = isset($p['pass']) ? ':' . $p['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = isset($p['path']) ? $p['path'] : '';
$toquery = $custom_query ?? ($p['query'] ?? ''); // get query string -> the given one, or the one that already exists.
$query = (strlen($toquery) > 0 ? '?'.$toquery : ''); // add the question mark only if has query.
$fragment = isset($p['fragment']) ? '#' . $p['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}
非常感谢您的帮助:)使用
parse\u url()
分解部分,使用parse\u str()
分解查询部分,取消设置您不需要的参数,然后使用http\u build\u query()
@AlexHowansky重建url这就是我在函数中所做的。我想我需要添加一个if
条件,以确保URL中有一个查询。但是我正在寻找一个更好的解决方案,如果它真的存在的话..哦哈,我只注意到了第一个func,heh sorry.FYI,比如http://example.com?myquestion=are+你+这里?
,第二个问号(参数值的一部分)真的应该由生成该URL的任何人/任何人编码。因此,您给出的示例真的不应该出现。parse_str($p['query']?'',$vars)
这很奇怪,当执行少量删除时(比如10次而不是300000次),似乎parse_url
更快。可能其中一次是系统相关的(我不确定)。这两种方法都能解决你的问题,并且跑得足够快,所以不用为它们操心。“过早优化是万恶之源。”(克努特,大卫)。
Time regex: 2.1999499797821
Time parse_url: 2.8799331188202
function removeGetParameter($url, $varname) {
$p = parse_url($url); // parse the url to parts.
parse_str($p['query'] ?? '', $vars); // make an array of the parameters if exist ($vars)
unset($vars[$varname]); // unset the unwanted
$vars_str = http_build_query($vars); // build the query string
return unparse_url($p, $vars_str);
}
function unparse_url($p, $custom_query = NULL) {
// my customization to http://php.net/manual/en/function.parse-url.php thomas at gielfeldt dot com
$scheme = isset($p['scheme']) ? $p['scheme'] . '://' : '';
$host = isset($p['host']) ? $p['host'] : '';
$port = isset($p['port']) ? ':' . $p['port'] : '';
$user = isset($p['user']) ? $p['user'] : '';
$pass = isset($p['pass']) ? ':' . $p['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = isset($p['path']) ? $p['path'] : '';
$toquery = $custom_query ?? ($p['query'] ?? ''); // get query string -> the given one, or the one that already exists.
$query = (strlen($toquery) > 0 ? '?'.$toquery : ''); // add the question mark only if has query.
$fragment = isset($p['fragment']) ? '#' . $p['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}