Como remover a string de consulta e obter apenas o URL?

201

Estou usando o PHP para criar o URL da página atual. Às vezes, URLs na forma de

www.mydomian.com/myurl.html?unwantedthngs

são solicitados. Quero remover ?oe tudo o que se segue (querystring), para que o URL resultante se torne:

www.mydomain.com/myurl.html

Meu código atual é este:

<?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;
}
?>
Navi Gamage
fonte
8
BTW, isso é chamado de "string de consulta".
Evan Mulawski

Respostas:

578

Você pode usar strtokpara obter string antes da primeira ocorrência de?

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

strtok()representa a técnica mais concisa para extrair diretamente a substring antes do ?na querystring. explode()é menos direto porque deve produzir uma matriz de dois elementos potencialmente pela qual o primeiro elemento deve ser acessado.

Algumas outras técnicas podem ser interrompidas quando a string de consulta estiver ausente ou potencialmente alterar outras substrings não desejadas no URL - essas técnicas devem ser evitadas.

Uma demonstração :

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

Resultado:

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
)
---
RiaD
fonte
24
+1 por usar $ _SERVER diretamente em vez de reconstruir o URL apenas para analisá-lo novamente. daria outro +1, se possível, por concisão.
Ericsoco 30/09/12
8
Ops - inverta esses argumentos para explodir (), o delimitador será o primeiro. array_shift(explode('?',$_SERVER["REQUEST_URI"]))
aqui
13
Não retorna bool (false) se? não está presente na string, ela retorna a string.
Ben C
4
Ótimo! .. Ainda está retornando o URL, mesmo que ?não esteja presente.
Harikrishnan
1
@sepehr, simplesmente não vejo sentido em não usar a função que faz exatamente o que você precisa e usa outro e analisa o resultado (ou seja, obtém [0] após explodir) (a menos, é claro, que exista uma razão específica como melhor desempenho , falta de dependência desnecessária, etc).
Riad
66

Use o Manual do PHP - parse_url () para obter as peças que você precisa.

Editar (exemplo de uso para @Navi Gamage)

Você pode usá-lo assim:

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

    return $constructed_url;
}

?>

Editar (segundo exemplo completo):

Função atualizada para garantir que o esquema seja anexado e nenhuma mensagem de aviso seja exibida:

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

Retornará:

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
)

Esta é a saída do exemplo de transmissão de URLs através de parse_url () sem segundo parâmetro (apenas para explicação).

E este é o resultado final após a construção do URL usando:

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

Resultado:

http://www.mydomian.com/myurl.html
http://www.mydomian.com/myurl.html
http://www.mydomian.com
https://mydomian.com/myurl.html
veritas
fonte
Eu li isso .. Estou um pouco confuso, porque se novo no php. Você pode me ajudar com o código php acima?
Navi Gamage
eu adicionei esse código após a linha 9 $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?"));
Navi Gamage
Ele clea seção de consulta no URL ...> www.mydomain.com/myurl.html?unwantedthings result is Okay! > Www.mydomian.com/myurl.html Feito ... Mas quando ele vem com url normais> resultado www.mydomain.com/myurl.html é nothing..Empty
Navi Gamage
strrpos () em 'www.mydomain.com/myurl.html' retornará 0 (FALSE convertido para booleano para ser mais correto) para que seu substr fique vazio. Use um : substr () OR parse_url () porque usar tanto faz sentido;)
veritas
Eu quis dizer FALSE convertido para int; D
veritas
54

melhor solução:

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

Não é necessário incluir seu http://domain.com no seu se você estiver enviando um formulário para o mesmo domínio.

Ludo - Fora de registro
fonte
Observe que parse_url espera um URL absoluto; portanto, você obterá resultados incorretos em alguns casos, por exemplo, se seu REQUEST_URL iniciar com várias barras consecutivas. Esses serão interpretados como um URI relativo ao protocolo.
NikiC
16
$val = substr( $url, 0, strrpos( $url, "?"));
zellio
fonte
Caras cordões de suas respostas Im done..thanks para seção de seus help..It cleas consulta na url ...
Navi Gamage
> www.mydomain.com/myurl.html?unwantedthings result is Okay! > Www.mydomian.com/myurl.html Feito ... Mas quando ele vem com url normais> resultado www.mydomain.com/myurl.html é nothing..Empty
Navi Gamage
Novo código 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, "?")); } retornar $ pageURL; }?>code
Navi Gamage
2
Penso que esta é uma solução bastante doce e simples para o problema. Não há necessidade de cargas de extensões ou funções. Eu usei isso para obter o nome do arquivo chamado atual. $ base = nome do base ($ _ SERVER ['REQUEST_URI']); $ page = substr ($ base, 0, strrpos ($ base, "?"));
22413 Rob
Como afirma Navi, esta resposta não é confiável. 3v4l.org/nhVii Se a string de consulta estiver ausente no URL, o URL inteiro será removido! Essa técnica não reconhece os componentes de URL. Esta resposta é desaconselhável.
mickmackusa 26/02
9

Maneira mais fácil

$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
Mukesh Saxena
fonte
Discordo que esta é a maneira mais fácil. Não, o texto em negrito não torna sua declaração mais atraente. Esta resposta está faltando uma explicação.
mickmackusa 26/02
@mickmackusa Você poderia elaborar seu comentário? Onde preciso explicar minha resposta? Eu serei grato a você.
Mukesh Saxena
Todas as respostas no Stackoverflow devem incluir uma explicação de como a solução funciona e por que você acha que é uma técnica ideal. Links para a documentação também são bem-vindos. Entendo perfeitamente sua solução, mas outro pesquisador pode não. As respostas somente de código são de baixo valor no Stackoverflow, porque fazem muito pouco para educar / capacitar milhares de futuros pesquisadores. Sobre não ser mais simples - 3v4l.org/RE0GD seria uma versão mais simples de sua resposta, pois possui menos variáveis ​​declaradas e faz apenas uma substituição em vez de duas. A resposta aceita é a mais simples de todas.
mickmackusa 26/02
Outra diferença é que a resposta aceita também cuida de um possível fragmento, mas a sua não. 3v4l.org/ERr4V ou pior, poderia alterar o URL à esquerda da querystring 3v4l.org/L61q1
mickmackusa 26/02
4

Você pode usar a construção parse_url na função assim:

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

Podes tentar:

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

Se você deseja obter o caminho da solicitação ( mais informações ):

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

Se você deseja remover a consulta e (e talvez fragmentar também):

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);
user1079877
fonte
1

Para remover a string de consulta do URI da solicitação, substitua a string de consulta por uma string vazia:

function request_uri_without_query() {
    $result = $_SERVER['REQUEST_URI'];
    $query = $_SERVER['QUERY_STRING'];
    if(!empty($query)) {
        $result = str_replace('?' . $query, '', $result);
    }
    return $result;
}
Ryan Prechel
fonte
Eu acho que haveria um problema em potencial www.example.com/myurl.html?.
Earlee
1

Como trato de URLs relativos e absolutos, atualizei a solução da veritas como o código abaixo.
Você pode tentar aqui: 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;
}
trante
fonte
1

também poderia usar o seguinte conforme o comentário manual do php

$_SERVER['REDIRECT_URL']

Observe que isso funciona apenas para determinados ambientes PHP e siga o comentário a seguir nessa página para obter mais informações;

Objetivo: O nome do caminho da URL do arquivo PHP atual, path-info é N / A e exclui a string de consulta da URL. Inclui barra principal.

Advertência: isso é antes de o URL ser reescrito (ou seja, conforme o URL da chamada original).

Advertência: não está definido em todos os ambientes PHP e, definitivamente, apenas nos com reescritas de URL.

Funciona no modo web: Sim

Funciona no modo CLI: Não

Janith Chinthana
fonte
0

Tente isto

$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);
kwelsan
fonte
0

Supondo que você ainda deseja obter a URL sem os argumentos da consulta (se eles não estiverem definidos), use apenas uma instrução shorthand if para verificar com strpos:

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

Aqui está uma solução simples se você estiver usando o Laravel:

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

Tente o seguinte:

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

ou

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']
HRALDA
fonte
1
Desculpe, mas isso está errado - o URI pode ser reescrito pelo htaccess - isso resultaria no retorno do nome do script, mas não no URI atual.
Hexodus
Perigoso, pois pode ser falsificado.
tim
confirmar está errado. suponha que você esteja escrevendo proxy.php, que é .htaccess redireciona para solicitações de vários recursos, como index.php, prices.php, about.php, e cria dinamicamente uma exibição para o nome solicitado. se você usar isso, o script sempre verá proxy.php em vez do recurso solicitado desejado que ele deseja criar.
Dmitry