Comment supprimer la chaîne de requête et obtenir uniquement l'URL?

201

J'utilise PHP pour créer l'URL de la page actuelle. Parfois, des URL sous forme de

www.mydomian.com/myurl.html?unwantedthngs

sont demandés. Je veux supprimer le ?et tout ce qui le suit (chaîne de requête), de sorte que l'URL résultante devienne:

www.mydomain.com/myurl.html

Mon code actuel est le suivant:

<?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
la source
8
BTW, c'est ce qu'on appelle la "chaîne de requête".
Evan Mulawski

Réponses:

578

Vous pouvez utiliser strtokpour obtenir une chaîne avant la première occurrence de?

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

strtok()représente la technique la plus concise pour extraire directement la sous-chaîne avant la chaîne ?de requête. explode()est moins direct car il doit produire un tableau potentiellement à deux éléments par lequel le premier élément doit être accédé.

Certaines autres techniques peuvent se casser lorsque la chaîne de requête est manquante ou potentiellement muter d'autres sous-chaînes / involontaires dans l'URL - ces techniques doivent être évitées.

Une démonstration :

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

Production:

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
la source
24
+1 pour utiliser directement $ _SERVER au lieu de reconstruire l'url uniquement pour la réanalyser. donnerait un autre +1 si possible, pour la concision.
ericsoco
8
Oups - inversez ces arguments pour explode (), le délimiteur commence en premier. array_shift(explode('?',$_SERVER["REQUEST_URI"]))
ici
13
Il ne retourne pas booléen (faux) si? n'est pas présent dans la chaîne, il renvoie la chaîne.
Ben C
4
Super! .. Il retourne toujours l'url même s'il ?n'est pas présent.
Harikrishnan
1
@sepehr, je ne vois aucun intérêt à ne pas utiliser une fonction qui fait exactement ce dont vous avez besoin et à en utiliser une autre et à en analyser le résultat (c.-à-d. obtenir [0] après l'explosion) (à moins bien sûr qu'il y ait une raison spécifique comme de meilleures performances , manque de dépendance inutile, etc.).
RiaD
66

Utilisez PHP Manual - parse_url () pour obtenir les pièces dont vous avez besoin.

Modifier (exemple d'utilisation pour @Navi Gamage)

Vous pouvez l'utiliser comme ceci:

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

    return $constructed_url;
}

?>

Modifier (deuxième exemple complet):

Fonction mise à jour pour s'assurer que le schéma sera attaché et aucun message de notification n'apparaît:

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

Reviendra:

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
)

Il s'agit de la sortie du passage d'exemples d'URL via parse_url () sans second paramètre (pour explication uniquement).

Et ceci est la sortie finale après avoir construit l'url en utilisant:

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

Production:

http://www.mydomian.com/myurl.html
http://www.mydomian.com/myurl.html
http://www.mydomian.com
https://mydomian.com/myurl.html
veritas
la source
Je l'ai lu .. Im un peu confus parce que nouveau pour php.Pouvez-vous m'aider avec le code php ci-dessus?
Navi Gamage
j'ai ajouté ce code après la ligne 9 $ pageURL = substr ($ pageURL, 0, strrpos ($ pageURL, "?"));
Navi Gamage
Il cleas section de requête dans l'url ...> www.mydomain.com/myurl.html?unwantedthings résultat est OK! > www.mydomian.com/myurl.html Fait ... Mais quand il s'agit d'une URL normale> www.mydomain.com/myurl.html le résultat n'est rien
Navi Gamage
strrpos () dans 'www.mydomain.com/myurl.html' renverra 0 (FALSE casté en booléen pour être plus correct) donc votre substr sera vide. Utilisez un : substr () OU parse_url () car utiliser les deux n'a aucun sens;)
veritas
Je voulais dire FAUX moulé en int; D
veritas
54

meilleure solution:

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

Pas besoin d'inclure votre http://domain.com dans votre si vous soumettez un formulaire au même domaine.

Ludo - Off the record
la source
Notez que parse_url attend une URL absolue, vous obtiendrez donc des résultats incorrects dans certains cas, par exemple si votre REQUEST_URL commence par plusieurs barres obliques consécutives. Ceux-ci seront interprétés comme un URI relatif au protocole.
NikiC
16
$val = substr( $url, 0, strrpos( $url, "?"));
zellio
la source
Les gars à vos réponses Im done..merci pour votre aide..Il cleas section de requête dans l'URL ...
Navi Gamage
> www.mydomain.com/myurl.html?unwantedthings est OK! > www.mydomian.com/myurl.html Fait ... Mais quand il s'agit d'une URL normale> www.mydomain.com/myurl.html le résultat n'est rien
Navi Gamage
Nouveau code 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
Je pense que c'est une solution plutôt douce et simple au problème. Pas besoin de charges d'extensions ou de fonctions. J'ai utilisé cela pour obtenir le nom de fichier appelé actuel. $ base = basename ($ _ SERVER ['REQUEST_URI']); $ page = substr ($ base, 0, strrpos ($ base, "?"));
Rob
Comme l'a déclaré Navi, cette réponse n'est pas fiable. 3v4l.org/nhVii Si la chaîne de requête est absente dans l'url, l'url entière est supprimée! Cette technique n'est pas compatible avec les composants URL. Cette réponse est déconseillée.
mickmackusa
9

Le moyen le plus simple

$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
la source
Je ne suis pas d'accord que c'est la manière la plus simple. Non, le texte en gras ne rend pas votre déclaration plus convaincante. Cette réponse manque d'explication.
mickmackusa
@mickmackusa Pourriez-vous s'il vous plaît élaborer votre commentaire? Où dois-je expliquer ma réponse? Je vous en serai reconnaissant.
Mukesh Saxena
Toutes les réponses sur Stackoverflow doivent inclure une explication du fonctionnement de la solution et pourquoi vous pensez que c'est une technique idéale. Les liens vers la documentation sont également les bienvenus. Je comprends parfaitement votre solution, mais d'autres chercheurs ne le savent peut-être pas. Les réponses de code uniquement ont une faible valeur sur Stackoverflow car elles font très peu pour éduquer / responsabiliser des milliers de futurs chercheurs. À propos de ne pas être le plus simple - 3v4l.org/RE0GD serait une version plus simple de votre réponse car il a moins de variables déclarées et ne fait qu'un seul remplacement au lieu de deux. La réponse acceptée est la plus simple de toutes.
mickmackusa
Une autre différence est que la réponse acceptée prend également en charge un éventuel fragment, mais pas la vôtre. 3v4l.org/ERr4V ou pire, il pourrait modifier l'url à gauche de la chaîne de requête 3v4l.org/L61q1
mickmackusa
4

Vous pouvez utiliser la fonction build de parse_url comme ça:

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

Tu peux essayer:

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

Si vous souhaitez obtenir le chemin de la demande ( plus d'informations ):

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

Si vous souhaitez supprimer la requête et (et peut-être aussi fragmenter):

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
la source
1

Pour supprimer la chaîne de requête de l'URI de la demande, remplacez la chaîne de requête par une chaîne vide:

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
la source
Je pense qu'il y aurait un problème potentiel avec www.example.com/myurl.html?.
Earlee
1

Étant donné que je gère des URL relatives et absolues, j'ai mis à jour la solution de Veritas comme le code ci-dessous.
Vous pouvez vous essayer ici: 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
la source
1

pourrait également utiliser la suite selon le commentaire du manuel php

$_SERVER['REDIRECT_URL']

Veuillez noter que cela ne fonctionne que pour certains environnements PHP uniquement et suivez le commentaire ci-dessous de cette page pour plus d'informations;

Objectif: Le nom du chemin URL du fichier PHP actuel, chemin-info est N / A et exclut la chaîne de requête URL. Comprend une barre oblique.

Mise en garde: c'est avant la réécriture de l'URL (c'est-à-dire selon l'URL d'appel d'origine).

Avertissement: non défini sur tous les environnements PHP, et certainement uniquement sur ceux avec réécriture d'URL.

Fonctionne en mode Web: Oui

Fonctionne en mode CLI: Non

Janith Chinthana
la source
0

Essaye ça

$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
la source
0

En supposant que vous souhaitiez toujours obtenir l'URL sans les arguments de la requête (s'ils ne sont pas définis), utilisez simplement une instruction raccourcie if pour vérifier strpos:

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

Voici une solution simple si vous utilisez Laravel:

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

Essaye ça:

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

ou

$urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']
HRALDA
la source
1
Désolé mais c'est faux - l'URI peut être réécrit par htaccess - cela entraînerait le retour du nom du script mais pas l'URI actuel.
Hexodus
Dangereux car il peut être usurpé.
tim
confirmer est faux. supposons que vous écrivez proxy.php, qui est. si vous l'utilisez, le script verra toujours proxy.php plutôt que la ressource demandée souhaitée qu'il souhaite construire.
Dmitry