使用PHP去除URL参数

时间:2011-02-08 19:37:48

标签: php

我在powerpoint演示文稿中有一些链接,出于某种原因,当点击这些链接时,它会向URL添加一个返回参数。好吧,那个返回参数导致我的Joomla网站的MVC模式被搞砸了。

那么,使用PHP去除这个返回参数的有效方法是什么??

实施例: http://mydomain.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0

19 个答案:

答案 0 :(得分:76)

最安全的“正确”方法是:

  1. 使用parse_url()
  2. 将网址解析为数组
  3. 提取查询部分,使用parse_str()
  4. 将其分解为数组
  5. 从数组
  6. 中删除unset()所需的查询参数
  7. 使用http_build_query()
  8. 重建原始网址

    快速而肮脏的是使用字符串搜索/替换和/或正则表达式来消除该值。

答案 1 :(得分:51)

在另一个主题中,Justin建议最快的方法是使用strtok()

 $url = strtok($url, '?');

在这里查看速度测试的完整答案:https://stackoverflow.com/a/1251650/452515

答案 2 :(得分:20)

这是用一个例子补充 Marc B 的答案,虽然它可能看起来很长,但这是一种删除参数的安全方法。在此示例中,我们删除了page_number

<?php
$x = 'http://url.com/search/?location=london&page_number=1';

$parsed = parse_url($x);
$query = $parsed['query'];

parse_str($query, $params);

unset($params['page_number']);
$string = http_build_query($params);
var_dump($string);

答案 3 :(得分:11)

parse_str($queryString, $vars);
unset($vars['return']);
$queryString = http_build_query($vars);

parse_str解析查询字符串,http_build_query创建查询字符串。

答案 4 :(得分:9)

你可以做preg_replace之类的:

$new_url = preg_replace('/&?return=[^&]*/', '', $old_url);

答案 5 :(得分:8)

这种方法中的一种,未经测试,但应该有效。

$link = 'http://mydomain.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0';
$linkParts = explode('&return=', $link);
$link = $linkParts[0];

答案 6 :(得分:7)

以下是“最安全'正确'方法”的实际代码......

function reduce_query($uri = '') {
    $kill_params = array('gclid');

    $uri_array = parse_url($uri);
    if (isset($uri_array['query'])) {
        // Do the chopping.
        $params = array();
        foreach (explode('&', $uri_array['query']) as $param) {
          $item = explode('=', $param);
          if (!in_array($item[0], $kill_params)) {
            $params[$item[0]] = isset($item[1]) ? $item[1] : '';
          }
        }
        // Sort the parameter array to maximize cache hits.
        ksort($params);
        // Build new URL (no hosts, domains, or fragments involved).
        $new_uri = '';
        if ($uri_array['path']) {
          $new_uri = $uri_array['path'];
        }
        if (count($params) > 0) {
          // Wish there was a more elegant option.
          $new_uri .= '?' . urldecode(http_build_query($params));
        }
        return $new_uri;
    }
    return $uri;
}

$_SERVER['REQUEST_URI'] = reduce_query($_SERVER['REQUEST_URI']);

但是,由于这可能存在于应用程序的引导程序之前,因此您应该将其放入匿名函数中。像这样......

call_user_func(function($uri) {
    $kill_params = array('gclid');

    $uri_array = parse_url($uri);
    if (isset($uri_array['query'])) {
        // Do the chopping.
        $params = array();
        foreach (explode('&', $uri_array['query']) as $param) {
          $item = explode('=', $param);
          if (!in_array($item[0], $kill_params)) {
            $params[$item[0]] = isset($item[1]) ? $item[1] : '';
          }
        }
        // Sort the parameter array to maximize cache hits.
        ksort($params);
        // Build new URL (no hosts, domains, or fragments involved).
        $new_uri = '';
        if ($uri_array['path']) {
          $new_uri = $uri_array['path'];
        }
        if (count($params) > 0) {
          // Wish there was a more elegant option.
          $new_uri .= '?' . urldecode(http_build_query($params));
        }
        // Update server variable.
        $_SERVER['REQUEST_URI'] = $new_uri;

    }
}, $_SERVER['REQUEST_URI']);

注意:已更新urldecode()以避免双重编码via http_build_query()功能。 注意:更新为ksort()以允许没有错误的参数没有错误。

答案 7 :(得分:7)

function removeParam($url, $param) {
    $url = preg_replace('/(&|\?)'.preg_quote($param).'=[^&]*$/', '', $url);
    $url = preg_replace('/(&|\?)'.preg_quote($param).'=[^&]*&/', '$1', $url);
    return $url;
}

答案 8 :(得分:6)

Marc B's程序实现完善后的答案Sergey Telshevsky's答案。

function strip_param_from_url( $url, $param )
{
    $base_url = strtok($url, '?');              // Get the base url
    $parsed_url = parse_url($url);              // Parse it 
    $query = $parsed_url['query'];              // Get the query string
    parse_str( $query, $parameters );           // Convert Parameters into array
    unset( $parameters[$param] );               // Delete the one you want
    $new_query = http_build_query($parameters); // Rebuilt query string
    return $base_url.'?'.$new_query;            // Finally url is ready
}

// Usage
echo strip_param_from_url( 'http://url.com/search/?location=london&page_number=1', 'location' )

答案 9 :(得分:3)

非常简单

$link = "http://example.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0"
echo substr($link, 0, strpos($link, "return") - 1);
//output : http://example.com/index.php?id=115&Itemid=283

答案 10 :(得分:3)

哇,这里有很多例子。我提供一个做错误处理的人。它使用要删除的query-string-param重建并返回整个URL,并将其删除。它还提供了一个奖励功能,可以动态构建当前的URL。经过测试,有效!

感谢Mark B的步骤。这是tpow的“剥离此返回参数”原始问题的完整解决方案 - 对初学者来说可能很方便,试图避免PHP陷阱。 : - )

<?php

function currenturl_without_queryparam( $queryparamkey ) {
    $current_url = current_url();
    $parsed_url = parse_url( $current_url );
    if( array_key_exists( 'query', $parsed_url )) {
        $query_portion = $parsed_url['query'];
    } else {
        return $current_url;
    }

    parse_str( $query_portion, $query_array );

    if( array_key_exists( $queryparamkey , $query_array ) ) {
        unset( $query_array[$queryparamkey] );
        $q = ( count( $query_array ) === 0 ) ? '' : '?';
        return $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'] . $q . http_build_query( $query_array );
    } else {
        return $current_url;
    }
}

function current_url() {
    $current_url = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
    return $current_url;
}

echo currenturl_without_queryparam( 'key' );

?>

答案 11 :(得分:2)

$var = preg_replace( "/return=[^&]+/", "", $var ); 
$var = preg_replace( "/&{2,}/", "&", $var );

第二行将取代&amp;&amp;到&amp;

答案 12 :(得分:2)

@MarcB提到使用正则表达式删除url参数很脏。是的,因为它并不像它看起来那么容易:

$scope.seeError = function(form,num,value){
    form.val.$error.required = false;
    form.val.$error.shouldBeNumber = false;
    if (value===undefined) // omit as form will show an error
        form.val.$error.required = true;
    if (num===1&&isNaN(Number(value))) // should be a number
        form.val.$error.shouldBeNumber = true;
};

返回:

Original
example.com/?foo=bar
example.com/?bar=foo&foo=bar
example.com/?foo=bar&bar=foo

@AaronHathaway
example.com/?
example.com/?bar=foo
example.com/?&bar=foo

@SergeS
example.com/?
example.com/?bar=foo&
example.com/?&bar=foo

@Justin
example.com/?
example.com/?bar=foo&
example.com/?bar=foo

@kraftb
example.com/
example.com/?bar=foo
example.com/?bar=foo

My version
example.com/
example.com/?bar=foo
example.com/?bar=foo

正如您所看到的,只有@kraftb使用正则表达式发布了正确的答案,而且我的版本稍微小一些。

答案 13 :(得分:1)

从当前页面删除获取参数

<?php
$url_dir=$_SERVER['REQUEST_URI']; 

$url_dir_no_get_param= explode("?",$url_dir)[0];

echo $_SERVER['HTTP_HOST'].$url_dir_no_get_param;

答案 14 :(得分:0)

function remove_attribute($url,$attribute)
 {
    $url=explode('?',$url);
    $new_parameters=false;
    if(isset($url[1]))
    {
        $params=explode('&',$url[1]);
        $new_parameters=ra($params,$attribute);
    }
    $construct_parameters=($new_parameters && $new_parameters!='' ) ? ('?'.$new_parameters):'';
    return $new_url=$url[0].$construct_parameters;
 }
 function ra($params,$attr)
    {   $attr=$attr.'=';
        $new_params=array();

        for($i=0;$i<count($params);$i++)
        {   
            $pos=strpos($params[$i],$attr);

            if($pos===false)
            $new_params[]=$params[$i];

        }
        if(count($new_params)>0)
        return implode('&',$new_params);
        else 
        return false; 
     }

//只需复制上面的代码,只需调用此函数即可获取没有特定参数的新网址

echo remove_attribute($ url,'delete_params'); //给出没有该参数的新网址

答案 15 :(得分:0)

这应该做到:

public function removeQueryParam(string $url, string $param): string
{
    $parsedUrl = parse_url($url);

    if (isset($parsedUrl[$param])) {
        $baseUrl = strtok($url, '?');
        parse_str(parse_url($url)['query'], $query);
        unset($query[$param]);
        return sprintf('%s?%s',
            $baseUrl,
            http_build_query($query)
        );
    }

    return $url;
}

答案 16 :(得分:0)

适用于每个网址的简单解决方案

使用此解决方案 $url 格式或参数位置无关紧要,例如我在 $url 末尾添加了另一个参数和锚点:

https://example.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0&bonus=test#test2

这是一个简单的解决方案:

$url = 'https://example.com/index.php?id=115&Itemid=283&return=aHR0cDovL2NvbW11bml0&bonus=test#test2';

$url_query_stirng = parse_url($url, PHP_URL_QUERY);
parse_str( $url_query_stirng, $url_parsed_query );
unset($url_parsed_query['return']);
$url = str_replace( $url_query_stirng, http_build_query( $url_parsed_query ), $url );

echo $url;

$url 字符串的最终结果是:

https://example.com/index.php?id=115&Itemid=283&bonus=test#test2

答案 17 :(得分:0)

我知道这是一个老问题,但如果您只想删除一个或几个命名的 url 参数,您可以使用此函数:

 const user = await prisma.user.findUnique({
        where: {
            id: userId,
        },
        include: {
            followers: true,   // list of followers for userId
            following: true,   // list of users that follow userId
        },
    });

在第一个函数中,function RemoveGet_Regex($variable, $rewritten_url): string { $rewritten_url = preg_replace("/(\?)$/", "", preg_replace("/\?&/", "?", preg_replace("/((?<=\?)|&){$variable}=[\w]*/i", "", $rewritten_url))); return $rewritten_url; } function RemoveGet($name): void { $rewritten_url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; if(is_array($name)) { for($i = 0; $i < count($name); $i++) { $rewritten_url = RemoveGet_Regex($name[$i], $rewritten_url); $is_set[] = isset($_GET[$name[$i]]); } $array_filtered = array_filter($is_set); if (!empty($array_filtered)) { header("Location: ".$rewritten_url); } } else { $rewritten_url = RemoveGet_Regex($name, $rewritten_url); if(isset($_GET[$name])) { header("Location: ".$rewritten_url); } } } 将删除 get 参数,其他函数将对其进行整理。然后第二个函数将重定向。

preg_replace("/((?<=\?)|&){$variable}=[\w]*/i", "", $rewritten_url) 将从网址中删除 RemoveGet("id");。该函数还可以处理数组。对于您的示例,

id=whatever

答案 18 :(得分:-1)

<? if(isset($_GET['i'])){unset($_GET['i']); header('location:/');} ?>

这将从URL中删除“i”参数。将'我改为你需要的任何东西。