Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP从给定URL中删除GET参数的最佳方法_Php_Regex_Url_Get - Fatal编程技术网

使用PHP从给定URL中删除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

很长一段时间以来,我一直在使用以下函数删除get参数:

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";
}