クエリ文字列を削除してURLのみを取得する方法は?


201

PHPを使用して現在のページのURLを作成しています。時々、の形式のURL

www.mydomian.com/myurl.html?unwantedthngs

要求されます。と?それに続くすべて(クエリ文字列)を削除して、結果のURLが次のようになるようにします。

www.mydomain.com/myurl.html

私の現在のコードはこれです:

<?php
function curPageURL() {
    $pageURL = 'http';
    if ($_SERVER["HTTPS"] == "on") {
        $pageURL .= "s";
    }
    $pageURL .= "://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"] . ":" .
            $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    return $pageURL;
}
?>

8
ところで、これは「クエリ文字列」と呼ばれます。
Evan Mulawski、2011

回答:


578

strtok最初に出現する前に文字列を取得するために使用できます?

$url = strtok($_SERVER["REQUEST_URI"], '?');

strtok()?クエリ文字列の前にある部分文字列を直接抽出する最も簡潔な手法を表します。 explode()最初の要素にアクセスする必要がある2要素の配列を生成する必要があるため、直接性は低くなります。

他のいくつかの手法は、クエリ文字列が見つからない場合や、URL内の他の/意図しない部分文字列を変更する可能性がある場合に機能しなくなる可能性があります。これらの手法は回避する必要があります。

デモ

$urls = [
    'www.example.com/myurl.html?unwantedthngs#hastag',
    'www.example.com/myurl.html'
];

foreach ($urls as $url) {
    var_export(['strtok: ', strtok($url, '?')]);
    echo "\n";
    var_export(['strstr/true: ', strstr($url, '?', true)]); // not reliable
    echo "\n";
    var_export(['explode/2: ', explode('?', $url, 2)[0]]);  // limit allows func to stop searching after first encounter
    echo "\n";
    var_export(['substr/strrpos: ', substr($url, 0, strrpos( $url, "?"))]);  // not reliable; still not with strpos()
    echo "\n---\n";
}

出力:

array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => 'www.example.com/myurl.html',
)
---
array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => false,                       // bad news
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => '',                          // bad news
)
---

24
もう一度解析するためだけにURLを再構築する代わりに、$ _ SERVERを直接使用する場合の+1。簡潔にするために、可能であれば別の+1を与えます。
ericsoco 2012

8
エラー:explode()の引数を逆にします。区切り文字が最初になります。 array_shift(explode('?',$_SERVER["REQUEST_URI"]))
こちらの

13
次の場合、bool(false)は返されません。文字列に存在しない場合は、文字列を返します。
ベンC

4
すばらしい!.. ?存在しない場合でも、URLを返します。
ハリクリシュナン2015

1
@sepehr、私はちょうどあなたが必要とするものを正確に実行する関数を使用せず、別の関数を使用して結果を解析する(つまり、爆発後に[0]を取得する)点をまったく見当たらない(もちろん、より良いパフォーマンスのような特定の理由がない限り) 、不要な依存関係の欠如など)。
RiaD 2015

66

PHPマニュアル-parse_url()を使用して、必要な部分を取得します。

編集(@Navi Gamageの使用例)

次のように使用できます。

<?php
function reconstruct_url($url){    
    $url_parts = parse_url($url);
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];

    return $constructed_url;
}

?>

編集(2番目の完全な例):

スキームがアタッチされ、通知メッセージが表示されないことを確認するために更新された関数:

function reconstruct_url($url){    
    $url_parts = parse_url($url);
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['path'])?$url_parts['path']:'');

    return $constructed_url;
}


$test = array(
    'http://www.mydomian.com/myurl.html?unwan=abc',
    'http://www.mydomian.com/myurl.html',
    'http://www.mydomian.com',
    'https://mydomian.com/myurl.html?unwan=abc&ab=1'
);

foreach($test as $url){
    print_r(parse_url($url));
}       

戻ります:

Array
(
    [scheme] => http
    [host] => www.mydomian.com
    [path] => /myurl.html
    [query] => unwan=abc
)
Array
(
    [scheme] => http
    [host] => www.mydomian.com
    [path] => /myurl.html
)
Array
(
    [scheme] => http
    [host] => www.mydomian.com
)
Array
(
    [path] => mydomian.com/myurl.html
    [query] => unwan=abc&ab=1
)

これは、例のURLを2番目のパラメーターなしでparse_url()に渡した結果です(説明のみ)。

そして、これは以下を使用してURLを構築した後の最終的な出力です。

foreach($test as $url){
    echo reconstruct_url($url) . '<br/>';
}   

出力:

http://www.mydomian.com/myurl.html
http://www.mydomian.com/myurl.html
http://www.mydomian.com
https://mydomian.com/myurl.html

私はそれを読みます。phpが初めての場合、少し混乱しています。上記のphpコードを手伝っていただけますか?
Navi Gamage、2011

このコードを9行目に追加しました$ pageURL = substr($ pageURL、0、strrpos($ pageURL、 "?"));
Navi Gamage、2011

これは、url ...> www.mydomain.com/myurl.html?unwantedthingsのクエリセクションで問題ありません。> www.mydomian.com/myurl.html完了...しかし、それは通常のURLが付属していたときに> www.mydomain.com/myurl.html結果はnothing..Emptyある
ナビガマゲ

'www.mydomain.com/myurl.html'内のstrrpos()は0(ブール値にキャストされるFALSEがより正確になるようにキャスト)を返すため、substrは空です。使用1:SUBSTR()ORでもparse_url()の両方が意味をなさない使用しているため;)
VERITAS

D;私はint型にキャストFALSEを意味
VERITAS

54

最善の解決策:

echo parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

同じドメインにフォームを送信する場合は、http://domain.comをに含める必要はありません。


parse_urlは絶対URLを想定しているため、REQUEST_URLが連続する複数のスラッシュで始まる場合など、場合によっては誤った結果が得られることに注意してください。これらはプロトコル相対URIとして解釈されます。
NikiC、2015

16
$val = substr( $url, 0, strrpos( $url, "?"));

イムは、URLでごhelp..It cleasクエリセクション...のためdone..thanksあなたの答えにcordingガイズ
ナビガマゲ

> www.mydomain.com/myurl.html?unwantedthings結果は大丈夫です!> www.mydomian.com/myurl.html完了...しかし、それは通常のURLが付属していたときに> www.mydomain.com/myurl.html結果はnothing..Emptyある
ナビガマゲ

新しいphpコード code <?php function curPageURL(){$ pageURL = 'http'; if($ _SERVER ["HTTPS"] == "on"){$ pageURL。= "s";} $ pageURL。= "://"; if($ _SERVER ["SERVER_PORT"]!= "80"){$ pageURL。= $ _SERVER ["SERVER_NAME"]。 ":"。$ _ SERVER ["SERVER_PORT"]。$ _ SERVER ["REQUEST_URI"]; } else {$ pageURL。= $ _SERVER ["SERVER_NAME"]。$ _ SERVER ["REQUEST_URI"]; $ pageURL = substr($ pageURL、0、strrpos($ pageURL、 "?")); } $ pageURLを返します。}?>code
Navi Gamage 2011

2
これは問題に対するかなり甘くてシンプルな解決策だと思います。大量の拡張機能や関数は必要ありません。これを使用して、現在呼び出されているファイル名を取得しました。$ base = basename($ _ SERVER ['REQUEST_URI']); $ page = substr($ base、0、strrpos($ base、 "?"));
ロブ

ナビで述べたように、この答えは信頼できません。3v4l.org/nhVii クエリ文字列がURLにない場合、URL全体が削除されます!この手法は、url-component-awareではありません。 この答えはお勧めできません。
mickmackusa

9

最も簡単な方法

$url = 'https://www.youtube.com/embed/ROipDjNYK4k?rel=0&autoplay=1';
$url_arr = parse_url($url);
$query = $url_arr['query'];
print $url = str_replace(array($query,'?'), '', $url);

//output
https://www.youtube.com/embed/ROipDjNYK4k

これが最も簡単な方法であることに同意しません。いいえ、太字のテキストはステートメントをより説得力のあるものにするものではありません。この答えには説明が足りません。
mickmackusa

@mickmackusaコメントについて詳しく教えてください。私の答えはどこに説明する必要がありますか?私はあなたに感謝します。
ムケシュサクセナ

Stackoverflowに関するすべての回答には、ソリューションがどのように機能するか、なぜソリューションが理想的な手法であると感じるのかの説明が含まれている必要があります。ドキュメントへのリンクも歓迎します。私はあなたの解決策を完全に理解していますが、他の研究者は理解していないかもしれません。Stackoverflowでは、コードのみの回答は価値が低く、何千人もの将来の研究者を教育/支援することはほとんどありません。最も単純ではない-3v4l.org/RE0GDは、宣言された変数が少なく、2つではなく1つだけ置換されるため、より簡単なバージョンの回答になります。受け入れられた答えは、すべての中で最も単純です。
mickmackusa

別の違いは、受け入れられた回答も可能なフラグメントを処理しますが、あなたの回答はしません。 3v4l.org/ERr4V またはそれより悪いと、クエリ文字列の左側にあるURLを壊す可能性があります3v4l.org/L61q1
mickmackusa


4

parse_urlビルドイン関数を次のように使用できます。

$baseUrl = $_SERVER['SERVER_NAME'] . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

2

あなたが試すことができます:

<?php
$this_page = basename($_SERVER['REQUEST_URI']);
if (strpos($this_page, "?") !== false) $this_page = reset(explode("?", $this_page));
?>

2

リクエストパスを取得する場合(詳細):

echo parse_url($_SERVER["REQUEST_URI"])['path']

クエリを削除したい場合(そしてフラグメント化したい場合):

function strposa($haystack, $needles=array(), $offset=0) {
        $chr = array();
        foreach($needles as $needle) {
                $res = strpos($haystack, $needle, $offset);
                if ($res !== false) $chr[$needle] = $res;
        }
        if(empty($chr)) return false;
        return min($chr);
}
$i = strposa($_SERVER["REQUEST_URI"], ['#', '?']);
echo strrpos($_SERVER["REQUEST_URI"], 0, $i);

1

リクエストURIからクエリ文字列を削除するには、クエリ文字列を空の文字列に置き換えます。

function request_uri_without_query() {
    $result = $_SERVER['REQUEST_URI'];
    $query = $_SERVER['QUERY_STRING'];
    if(!empty($query)) {
        $result = str_replace('?' . $query, '', $result);
    }
    return $result;
}

には潜在的な問題があると思いますwww.example.com/myurl.html?
Earlee

1

私は相対URLと絶対URLの両方を扱うため、以下のコードのようにVeritasのソリューションを更新しました。
ここで自分で試すことができます:https : //ideone.com/PvpZ4J

function removeQueryStringFromUrl($url) {
    if (substr($url,0,4) == "http") {
        $urlPartsArray = parse_url($url);
        $outputUrl = $urlPartsArray['scheme'] . '://' . $urlPartsArray['host'] . ( isset($urlPartsArray['path']) ? $urlPartsArray['path'] : '' );
    } else {
        $URLexploded = explode("?", $url, 2);
        $outputUrl = $URLexploded[0];
    }
    return $outputUrl;
}

1

phpのマニュアルコメントに従って、以下を使用することもできます

$_SERVER['REDIRECT_URL']

これは特定のPHP環境でのみ機能することに注意してください。詳細については、そのページの以下のコメントに従ってください。

目的:現在のPHPファイルのURLパス名、path-infoはN / Aで、URLクエリ文字列は除外されます。先行スラッシュを含みます。

警告:これは、URLが書き換えられる前です(つまり、元の呼び出しURLのとおりです)。

警告:すべてのPHP環境で設定されているわけではありません。URLの書き換えが可能な環境のみに限定されています。

Webモードで動作:はい

CLIモードで動作:いいえ


0

これを試して

$url_with_querystring = 'www.mydomian.com/myurl.html?unwantedthngs';
$url_data = parse_url($url_with_querystring);
$url_without_querystring = str_replace('?'.$url_data['query'], '', $url_with_querystring);

0

まだクエリ引数なしでURLを取得したい場合(設定されていない場合)、次のように確認するために省略形のifステートメントを使用しstrposます。

$request_uri = strpos( $_SERVER['REQUEST_URI'], '?' ) !== false ? strtok( $_SERVER["REQUEST_URI"], '?' ) : $_SERVER['REQUEST_URI'];

0

Laravelを使用している場合の簡単な解決策を次に示します。

Str::before($request->getRequestUri(), '?')

-3

これを試して:

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']

または

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']

1
申し訳ありませんが、これは間違っています-URIはhtaccessで書き換えることができます-これにより、現在のURIではなくスクリプト名が返されます。
Hexodus 2016

なりすましの可能性があるため危険です。
tim

確認は間違っています。.htaccessがindex.php、prices.php、about.phpなどのさまざまなリソースのリクエストからリダイレクトされ、リクエストされた名前のビューを動的に構築するproxy.phpを書いているとします。これを使用すると、スクリプトは、ビルドしたい要求されたリソースではなく、常にproxy.phpを参照します。
ドミトリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.