¿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;
}
?>
Navi Gamage
fuente
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
)
---
RiaD
fuente
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
veritas
fuente
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.

Ludo - Off the record
fuente
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, "?"));
zellio
fuente
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
Mukesh Saxena
fuente
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);
Mohammad altenji
fuente
2

Puedes probar:

<?php
$this_page = basename($_SERVER['REQUEST_URI']);
if (strpos($this_page, "?") !== false) $this_page = reset(explode("?", $this_page));
?>
ysrb
fuente
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);
usuario1079877
fuente
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;
}
Ryan Prechel
fuente
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;
}
trante
fuente
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

Janith Chinthana
fuente
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);
kwelsan
fuente
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'];
sMyles
fuente
0

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

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

Prueba esto:

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

o

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']
HRALDA
fuente
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