Jak usunąć kwerendę i uzyskać tylko adres URL?


201

Używam PHP do zbudowania adresu URL bieżącej strony. Czasami adresy URL w postaci

www.mydomian.com/myurl.html?unwantedthngs

są wymagane. Chcę usunąć ?i wszystko, co następuje po nim (kwerenda), tak aby wynikowy adres URL stał się:

www.mydomain.com/myurl.html

Mój obecny kod to:

<?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
BTW, to się nazywa „ciąg zapytania”.
Evan Mulawski,

Odpowiedzi:


577

Możesz użyć, strtokaby uzyskać ciąg przed pierwszym wystąpieniem?

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

strtok()reprezentuje najbardziej zwięzłą technikę bezpośredniego wyciągania podłańcucha przed ?kwerendą. explode()jest mniej bezpośredni, ponieważ musi wytworzyć potencjalnie dwuelementową tablicę, za pomocą której należy uzyskać dostęp do pierwszego elementu.

Niektóre inne techniki mogą się zepsuć, gdy brakuje kwerendy lub potencjalnie mutować inne / niezamierzone podciągi w adresie URL - technik tych należy unikać.

demonstracja :

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

Wynik:

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
+1 za bezpośrednie użycie $ _SERVER zamiast odbudowywania adresu URL tylko w celu jego ponownej analizy. dałoby kolejne +1, jeśli to możliwe, do rozstrzygnięcia.
ericsoco

8
Ups - odwróć te argumenty dla explode (), separator jest pierwszy. array_shift(explode('?',$_SERVER["REQUEST_URI"]))
tutaj

13
Nie zwraca bool (fałsz) jeśli? nie jest obecny w ciągu, zwraca ciąg.
Ben C

4
Świetnie! .. Nadal zwraca adres URL, nawet jeśli ?nie jest obecny.
Harikrishnan

1
@sepehr, po prostu nie widzę sensu, aby nie używać funkcji, która robi dokładnie to, czego potrzebujesz, i używać innej i analizować wynik (tj. uzyskać [0] po wybuchu) (chyba że istnieje konkretny powód, taki jak lepsza wydajność , brak zbędnej zależności itp.).
RiaD,

66

Użyj PHP Manual - parse_url (), aby uzyskać potrzebne części.

Edytuj (przykładowe użycie @Navi Gamage)

Możesz użyć tego w następujący sposób:

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

    return $constructed_url;
}

?>

Edycja (drugi pełny przykład):

Zaktualizowana funkcja, aby upewnić się, że schemat zostanie dołączony i nie pojawią się żadne powiadomienia:

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

Wróci:

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
)

To jest wynik z przekazywania przykładowych adresów URL przez parse_url () bez drugiego parametru (tylko dla wyjaśnienia).

I to jest końcowy wynik po zbudowaniu adresu URL przy użyciu:

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

Wynik:

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

Przeczytałem to ... Jestem trochę zdezorientowany, ponieważ jeśli jesteś nowy w php. Czy możesz mi pomóc z powyższym kodem php?
Navi Gamage,

dodałem ten kod po wierszu 9 $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, „?”));
Navi Gamage

Czyści sekcję zapytania w adresie URL ...> www.mydomain.com/myurl.html?unwantedthings wynik jest OK! > www.mydomian.com/myurl.html Gotowe ... Ale jeśli chodzi o normalny adres URL> www.mydomain.com/myurl.html wynik jest niczym .. Puste
Navi Gamage

strrpos () w 'www.mydomain.com/myurl.html' zwróci 0 (FAŁSZ rzutowany na wartość logiczną, aby być bardziej poprawnym), więc twój substr będzie pusty. Użyj one : substr () LUB parse_url (), ponieważ użycie obu nie ma sensu;)
veritas

Miałem na myśli FALSE casted do int; D
veritas

54

najlepsze rozwiązanie:

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

Jeśli przesyłasz formularz do tej samej domeny, nie musisz dołączać do niego swojej http://domain.com .


Pamiętaj, że parse_url oczekuje bezwzględnego adresu URL, więc w niektórych przypadkach otrzymasz nieprawidłowe wyniki, np. Jeśli REQUEST_URL zaczyna się od wielu kolejnych ukośników. Będą one interpretowane jako URI zależne od protokołu.
NikiC,

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

Faceci zgodnie z twoimi odpowiedziami Gotowe .. dziękuję za pomoc .. Czyści sekcję zapytania w adresie URL ...
Navi Gamage

> www.mydomain.com/myurl.html?unwantedthings wynik jest OK! > www.mydomian.com/myurl.html Gotowe ... Ale jeśli chodzi o zwykły adres URL> www.mydomain.com/myurl.html wynik jest niczym .. Puste
Navi Gamage

Nowy kod php code <? Funkcja php 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, „?”)); } return $ pageURL; }?>code
Navi Gamage,

2
Myślę, że jest to raczej słodkie i proste rozwiązanie problemu. Nie potrzeba mnóstwa rozszerzeń ani funkcji. Użyłem tego, aby uzyskać bieżącą nazwę pliku. $ base = basename ($ _ SERVER ['REQUEST_URI']); $ page = substr ($ base, 0, strrpos ($ base, "?"));
Rob

Jak stwierdził Navi, ta odpowiedź nie jest wiarygodna. 3v4l.org/nhVii Jeśli kwerenda nie występuje w adresie URL, cały adres URL jest usuwany! Ta technika nie rozpoznaje składników adresu URL. Ta odpowiedź jest niewskazana.
mickmackusa

9

Najłatwiejszy sposób

$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

Nie zgadzam się, że jest to najłatwiejsza droga. Nie, pogrubiony tekst nie zwiększa atrakcyjności Twojego oświadczenia. W tej odpowiedzi nie ma wyjaśnienia.
mickmackusa

@mickmackusa Czy mógłbyś rozwinąć swój komentarz? Gdzie muszę wyjaśnić swoją odpowiedź? Będę ci wdzięczny.
Mukesh Saxena

Wszystkie odpowiedzi na Stackoverflow powinny zawierać wyjaśnienie, jak działa rozwiązanie i dlaczego uważasz, że jest to idealna technika. Linki do dokumentacji są również mile widziane. W pełni rozumiem twoje rozwiązanie, ale inny badacz może nie. Tylko kodowe odpowiedzi mają niewielką wartość w Stackoverflow, ponieważ niewiele robią, aby edukować / wspierać tysiące przyszłych badaczy. O tym, że nie jest najprostszy - 3v4l.org/RE0GD byłby prostszą wersją twojej odpowiedzi, ponieważ ma mniej zadeklarowanych zmiennych i powoduje tylko jedną zamianę zamiast dwóch. Akceptowana odpowiedź jest najprostsza ze wszystkich.
mickmackusa

Kolejna różnica polega na tym, że zaakceptowana odpowiedź zajmuje się również możliwym fragmentem, ale twój nie. 3v4l.org/ERr4V lub gorzej może to Magiel URL do lewej strony kwerendy 3v4l.org/L61q1
mickmackusa


4

Możesz użyć wbudowanej funkcji parse_url w następujący sposób:

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

2

Możesz spróbować:

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

2

Jeśli chcesz uzyskać ścieżkę zapytania ( więcej informacji ):

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

Jeśli chcesz usunąć zapytanie i (a może także fragment):

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

Aby usunąć ciąg zapytania z identyfikatora URI żądania, zastąp ciąg zapytania pustym ciągiem:

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

Myślę, że byłby to potencjalny problem www.example.com/myurl.html?.
Earlee

1

Ponieważ mam do czynienia zarówno z względnymi, jak i bezwzględnymi adresami URL, zaktualizowałem rozwiązanie Veritas, takie jak poniższy kod.
Możesz spróbować tutaj: 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

może również użyć następujących zgodnie z komentarzem ręcznym php

$_SERVER['REDIRECT_URL']

Pamiętaj, że działa to tylko w niektórych środowiskach PHP i postępuj zgodnie z poniższym komentarzem z tej strony, aby uzyskać więcej informacji;

Cel: Nazwa ścieżki URL bieżącego pliku PHP, ścieżka-info to N / D, z wyłączeniem ciągu zapytania URL. Obejmuje wiodący ukośnik.

Zastrzeżenie: jest to przed przepisaniem adresu URL (tzn. Zgodnie z pierwotnym adresem URL połączenia).

Zastrzeżenie: Nie ustawione we wszystkich środowiskach PHP, a na pewno tylko w tych z przepisem adresów URL.

Działa w trybie internetowym: Tak

Działa w trybie CLI: Nie


0

Spróbuj tego

$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

Zakładając, że nadal chcesz uzyskać adres URL bez argumentów zapytania (jeśli nie są ustawione), po prostu użyj skróconej instrukcji if, aby sprawdzić za pomocą strpos:

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

0

Oto proste rozwiązanie, jeśli używasz Laravel:

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

-3

Spróbuj tego:

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

lub

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

1
Przykro nam, ale to źle - identyfikator URI może zostać przepisany przez htaccess - spowoduje to zwrócenie nazwy skryptu, ale nie bieżący identyfikator URI.
Heksodus

Niebezpieczne, ponieważ może być sfałszowane.
tim

potwierdź, że jest źle. Załóżmy, że piszesz proxy.php, który jest .htaccess przekierowuje z żądań różnych zasobów, takich jak index.php, prices.php, about.php, i dynamicznie buduje widok dla żądanej nazwy. jeśli go użyjesz, skrypt zawsze zobaczy proxy.php zamiast żądanego zasobu, który chce zbudować.
Dmitry
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.