¿Cómo eliminar la cadena de consulta y obtener solo la url?


201

Estoy usando PHP para construir la URL de la página actual. A veces, las URL en forma de

www.mydomian.com/myurl.html?unwantedthngs

son solicitados. Quiero eliminar el ?y todo lo que le sigue (cadena de consulta), de modo que la URL resultante se convierta en:

www.mydomain.com/myurl.html

Mi código actual es 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;
}
?>

8
Por cierto, eso se llama la "cadena de consulta".
Evan Mulawski

Respuestas:


578

Puede usar strtokpara obtener cadena antes de la primera aparición de?

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

strtok()representa la técnica más concisa para extraer directamente la subcadena antes ?de la cadena de consulta. explode()es menos directo porque debe producir una matriz potencialmente de dos elementos mediante la cual se debe acceder al primer elemento.

Algunas otras técnicas pueden romperse cuando falta la cadena de consulta o potencialmente mutar otras subcadenas no deseadas en la url; estas técnicas deben evitarse.

Una demostración :

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

Salida:

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 por usar $ _SERVER directamente en lugar de reconstruir la url solo para analizarla nuevamente. daría otro +1 si es posible, por concisión.
ericsoco

8
Oops: invierta esos argumentos para explotar (), el delimitador va primero. array_shift(explode('?',$_SERVER["REQUEST_URI"]))
aquí

13
No devuelve bool (falso) si? no está presente en la cadena, devuelve la cadena.
Ben C

44
¡Genial! ... Sigue devolviendo la url incluso si ?no está presente.
Harikrishnan

1
@sepehr, simplemente no veo ningún punto para no usar la función que hace exactamente lo que necesita y usar otra y analizar el resultado (es decir, obtener [0] después de explotar) (a menos, por supuesto, que haya una razón específica como un mejor rendimiento , falta de dependencia innecesaria, etc.).
RiaD

66

Use PHP Manual - parse_url () para obtener las partes que necesita.

Editar (ejemplo de uso para @Navi Gamage)

Puedes usarlo así:

<?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 ejemplo completo):

Se actualizó la función para asegurarse de que se adjuntará el esquema y no aparecerá ningún mensaje de aviso:

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

Volveremos:

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
)

Este es el resultado de pasar URL de ejemplo a través de parse_url () sin un segundo parámetro (solo para explicación).

Y este es el resultado final después de construir la URL usando:

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

Salida:

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

Lo leí ... Estoy un poco confundido porque soy nuevo en php. ¿Me pueden ayudar con el código php anterior?
Navi Gamage

agregué este código después de la línea 9 $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?"));
Navi Gamage

Limpia la sección de consulta en la url ...> www.mydomain.com/myurl.html?unwantedthings result is Okay! > www.mydomian.com/myurl.html Listo ... Pero cuando se trata de una url normal> www.mydomain.com/myurl.html el resultado no es nada
Navi Gamage

strrpos () en 'www.midominio.com/myurl.html' devolverá 0 (FALSO convertido a booleano para ser más correcto) por lo que su substr estará vacía. Use uno : substr () O parse_url () porque usar ambos no tiene sentido;)
veritas

Quise decir FALSO enviado a int; D
veritas

54

mejor solución:

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

No es necesario incluir su http://dominio.com en su si envía un formulario al mismo dominio.


Tenga en cuenta que parse_url espera una URL absoluta, por lo que obtendrá resultados incorrectos en algunos casos, por ejemplo, si su REQUEST_URL comienza con varias barras inclinadas consecutivas. Esos serán interpretados como un URI relativo al protocolo.
NikiC

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

Chicos de acuerdo a sus respuestas Estoy listo ... Gracias por su ayuda ... Limpia la sección de consulta en la url ...
Navi Gamage

> www.mydomain.com/myurl.html?unwantedthings resultado está bien! > www.mydomian.com/myurl.html Listo ... Pero cuando se trata de una URL normal> www.mydomain.com/myurl.html el resultado no es nada
Navi Gamage

Nuevo 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, "?")); } return $ pageURL; }?>code
Navi Gamage

2
Creo que esta es una solución bastante dulce y simple al problema. No hay necesidad de un montón de extensiones o funciones. Usé esto para obtener el nombre actual del archivo llamado. $ base = nombre base ($ _ SERVER ['REQUEST_URI']); $ página = substr ($ base, 0, strrpos ($ base, "?"));
Rob

Como declaró Navi, esta respuesta no es confiable. 3v4l.org/nhVii Si la cadena de consulta está ausente en la url, ¡se elimina toda la url! Esta técnica no es compatible con el componente url. Esta respuesta es desaconsejable.
mickmackusa

9

La forma más 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

No estoy de acuerdo con que esta sea la forma más fácil. No, el texto en negrita no hace que su declaración sea más convincente. Esta respuesta carece de explicación.
mickmackusa

@mickmackusa ¿Podría por favor elaborar su comentario? ¿Dónde necesito explicar mi respuesta? Te lo agradeceré.
Mukesh Saxena

Todas las respuestas en Stackoverflow deben incluir una explicación de cómo funciona la solución y por qué cree que es una técnica ideal. Los enlaces a la documentación también son bienvenidos. Entiendo completamente su solución, pero otro investigador puede que no. Las respuestas de solo código tienen poco valor en Stackoverflow porque hacen muy poco para educar / capacitar a miles de futuros investigadores. Acerca de no ser más simple: 3v4l.org/RE0GD sería una versión más simple de su respuesta porque tiene menos variables declaradas y hace solo un reemplazo en lugar de dos. La respuesta aceptada es la más simple de todas.
mickmackusa

Otra diferencia es que la respuesta aceptada también se ocupa de un posible fragmento, pero la suya no lo hará. 3v4l.org/ERr4V o peor, podría destrozar la url a la izquierda de la cadena de consulta 3v4l.org/L61q1
mickmackusa


4

Puede usar la función parse_url build in así:

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

2

Puedes probar:

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

2

Si desea obtener la ruta de solicitud ( más información ):

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

Si desea eliminar la consulta y (y quizás fragmentar también):

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

Para eliminar la cadena de consulta del URI de solicitud, reemplace la cadena de consulta con una cadena vacía:

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

Creo que habría un problema potencial con www.example.com/myurl.html?.
Earlee

1

Debido a que trato con URLs relativas y absolutas, actualicé la solución de veritas como el código a continuación.
Puedes probarlo aquí: 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

también podría usar el siguiente según el comentario manual de php

$_SERVER['REDIRECT_URL']

Tenga en cuenta que esto solo funciona para ciertos entornos PHP y siga el comentario de abajo de esa página para obtener más información;

Propósito: El nombre de la ruta URL del archivo PHP actual, la información de ruta es N / A y excluye la cadena de consulta URL. Incluye barra diagonal.

Advertencia: Esto es antes de que se reescriba la URL (es decir, según la URL de la llamada original).

Advertencia: no está configurado en todos los entornos PHP, y definitivamente solo en aquellos con reescrituras de URL.

Funciona en modo web: sí

Funciona en modo CLI: No


0

Prueba esto

$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

Suponiendo que todavía desea obtener la URL sin los argumentos de consulta (si no están configurados), solo use una instrucción abreviada if para verificar con strpos:

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

0

Aquí hay una solución simple si está utilizando Laravel:

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

-3

Prueba esto:

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

o

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

1
Lo sentimos, pero esto está mal: htaccess puede reescribir el URI, lo que daría como resultado que se devuelva el nombre del script pero no el URI actual.
Hexodus

Peligroso ya que puede ser falsificado.
tim

confirmar está mal. supongamos que está escribiendo proxy.php, que es .htaccess redirige a las solicitudes de varios recursos, como index.php, price.php, about.php, y crea dinámicamente una vista para el nombre solicitado. si usa esto, el script siempre verá proxy.php en lugar del recurso solicitado deseado que desea construir.
Dmitry
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.