PHP로 GET 변수를 제거하는 아름다운 방법?


94

GET 변수를 포함하는 전체 URL이있는 문자열이 있습니다. GET 변수를 제거하는 가장 좋은 방법은 무엇입니까? 그중 하나만 제거하는 좋은 방법이 있습니까?

이것은 작동하지만 그다지 아름답 지 않은 코드입니다 (제 생각에).

$current_url = explode('?', $current_url);
echo $current_url[0];

위의 코드는 모든 GET 변수를 제거합니다. 제 경우 URL은 CMS에서 생성되므로 서버 변수에 대한 정보가 필요하지 않습니다.


1
성능이 문제가되지 않는 한 당신이 가진 것을 고수 할 것입니다. Gumbo에서 제공하는 정규식 솔루션은 최대한 예쁘게 될 것입니다.
MitMaro

functions.php에 들어가거나 추악한 부분을 숨기는 곳이라면 아름답 지 않아도됩니다. qs_build () 만보고 호출하면됩니다
Question Mark

다음은 멋진 익명 함수를 통해이 작업을 수행하는 방법입니다. stackoverflow.com/questions/4937478/…
doublejosh

URL 조각은 어떻습니까? 아래에 표시된 솔루션은 코드가 수행하는 것처럼 조각도 삭제합니다.
Marten Koetsier 19-06-10

답변:


235

좋아, 모든 변수를 제거하려면 아마도 가장 예쁜 것은

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

strtok여기를 참조 하십시오 .

가장 빠르며 (아래 참조) '?'가없는 URL을 처리합니다. 정확히.

url + querystring을 가져 와서 하나의 변수 만 제거하려면 (정규식 바꾸기를 사용하지 않고 경우에 따라 더 빠를 수 있음) 다음과 같이 할 수 있습니다.

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가 이기고 지금까지 가장 작은 코드입니다.


좋아, 마음이 바뀌었다. strtok 방식이 더 좋아 보입니다. 다른 기능은 잘 작동하지 않았습니다. 이 get 변수에 대한 기능을 시도 했습니까? cbyear = 2013 & test = value 및 echo removeqsvar ($ current_url, 'cbyear'); 결과 : amp; test = value
Jens Törnell

아 예 ... 정규식이 완전하지 않습니다. 후행 구분 기호를 바꾸고 선행 구분 기호를 놓쳐 야합니다 (블라인드로 작성). 더 긴 기능은 여전히 ​​잘 작동합니다. preg_replace ( '/([?&])'.$ varname.'= [^ &] + (& | $) / ','$ 1 ', $ url) 작동해야 함
Justin

1
PHP 5.4는 @unset에 대해 불평하는 것 같습니다. 이상하게도 @ 기호를 좋아하지 않습니다.
Artem Russakovskii

1
당연히 @ 연산자 (오류 숨기기)는 어쨌든 악의적입니다-아마도 PHP 5.4에서 더 나은 방법이있을 것입니다.하지만 지금은 거의 2 년 동안 PHP를 작성하지 않았기 때문에 약간 벗어났습니다. 연습.
Justin

strtok를 바위, 한
FrancescoMM

33

어때 :

preg_replace('/\\?.*/', '', $str)

1
확실히 더 예뻐. 그래도 어느 것이 더 잘 수행 될지 궁금합니다. +1
MitMaro

이것은 저에게 몇 줄을 절약했으며 저에게는 짧고 아름답습니다. 감사합니다!
Jens Törnell

5
/(\\?|&)the-var=.*?(&|$)/특정 변수 만 제거하는 데 사용 합니다 ( the-var여기).

10

쿼리 문자열을 제거하려는 URL이 PHP 스크립트의 현재 URL 인 경우 이전에 언급 한 방법 중 하나를 사용할 수 있습니다. URL이 포함 된 문자열 변수가 있고 '?'뒤에있는 모든 것을 제거하려는 경우 넌 할 수있어:

$pos = strpos($url, "?");
$url = substr($url, 0, $pos);

+1은 질문에 답하고 대안을 제공하는 유일한 다른 답변이기 때문입니다.
MitMaro

2
URL에 ?. 그러면 코드가 빈 문자열을 반환합니다.
Gumbo

@Gumbo 말한 백업하려면 그래, 난에 두 번째 줄을 변경합니다 :$url = ($pos)? substr($url, 0, $pos) : $url;
CenterOrbit

7

@MitMaro의 의견에 영감을 받아 @Gumbo, @Matt Bridges 및 @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가 가장 빠릅니다.

참고 : Apache2 및 PHP5를 사용하는 로컬 Debian Lenny 시스템에서 테스트되었습니다.


정규 표현식 실행 시간 : 0.14591598510742 초; 폭발 실행 시간 : 0.07137393951416 초; strpos 실행 시간 : 0.080883026123047 초; tok 실행 시간 : 0.042459011077881 초;
Justin

아주 좋아요! 속도가 중요하다고 생각합니다. 그것은 일어날 유일한 일이 아닙니다. 웹 애플리케이션에는 수백 개의 기능이있을 수 있습니다. "모든 것이 세부 사항에 있습니다". 감사합니다. 투표하세요!
Jens Törnell

저스틴, 고마워. 이제 스크립트가 정리되고 솔루션을 고려합니다.
Scharrels

7

또 다른 해결책 ...이 함수가 더 우아하다는 것을 알았습니다. 또한 후행 '?'도 제거합니다. 제거 할 키가 쿼리 문자열에서 유일한 경우.

/**
 * 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에서이 테스트 실행


3

이를 위해 서버 변수를 사용할 수 없습니까?

아니면 작동할까요? :

unset($_GET['page']);
$url = $_SERVER['SCRIPT_NAME'] ."?".http_build_query($_GET);

그냥 생각.


2

이를 위해 서버 변수 를 사용할 수 있습니다 ( 예 $_SERVER['REQUEST_URI']:) $_SERVER['PHP_SELF'].


4
이것은 물론 그가 파싱하는 URL이 파싱을 수행하는 페이지라고 가정합니다.
MitMaro


0

$ _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>

0

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;

0

제 생각에는 가장 좋은 방법은 다음과 같습니다.

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

'i'GET 매개 변수가 있는지 확인하고 있으면 제거합니다.


0

echo'd javascript를 사용하여 자체 제출하는 빈 양식으로 모든 변수의 URL을 제거하십시오.

    <?
    if (isset($_GET['your_var'])){
    //blah blah blah code
    echo "<script type='text/javascript'>unsetter();</script>"; 
    ?> 

그런 다음이 자바 스크립트 함수를 만듭니다.

    function unsetter() {
    $('<form id = "unset" name = "unset" METHOD="GET"><input type="submit"></form>').appendTo('body');
    $( "#unset" ).submit();
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.