web-dev-qa-db-fra.com

Comment obtenir en toute sécurité l'URL complète du répertoire parent du courant PHP page

J'utilise:

$domain = $_SERVER['HTTP_Host'];
$path = $_SERVER['SCRIPT_NAME'];
$themeurl = $domain . $path;

Mais ceci donne bien sûr l'URL complète . À la place, je ai besoin de l'URL complète moins le fichier actuel et un répertoire au maximum et la barre oblique de fin.

ainsi, quel que soit le domaine de l'adresse URL du navigateur, par exemple localhost, https: //, http: //, etc., le chemin complet (sans aucune réécriture de mod) du chemin de l'URL du répertoire parent est indiqué sans barre oblique. 

Comment cela se passe-t-il? En toute sécurité, pas de XSS comme je suppose (en lisant), utiliser autre chose que 'SCRIPT_NAME' comporte un tel risque.

exemples: si donné:

https://stackoverflow.com/questions/somequestions/index.php

avoir besoin:

https://stackoverflow.com/questions

sans la barre oblique finale.

et devrait également travailler pour dire:

http://localhost/GetSimple/admin/load.php

obtenir

http://localhost/GetSimple

c'est ce que j'essaie de faire.

Je vous remercie.



Edit: Voici la solution de travail que j'ai utilisée:

$url  = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$url .= $_SERVER['SERVER_NAME'];
$url .= htmlspecialchars($_SERVER['REQUEST_URI']);
$themeurl = dirname(dirname($url)) . "/theme";

cela fonctionne parfaitement.

15
Rocket Spaceman

C'est facile - en utilisant la fonction dirname deux fois :)

echo dirname(dirname('https://stackoverflow.com/questions/somequestions/index.php'));

Notez également le commentaire de @ Sid. Lorsque vous avez besoin de l'URI complet du script actuel, avec protocole et serveur, utilisez quelque chose comme ceci:

$url  = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$url .= $_SERVER['SERVER_NAME'];
$url .= $_SERVER['REQUEST_URI'];

echo dirname(dirname($url));
31
hek2mgl

J'ai une syntaxe plus simple pour obtenir les adresses parent avec le port et l'URL Permet d'essayer mon code

dirname($_SERVER['PHP_SELF'])

avec ce code, vous pouvez obtenir un parent direct d’adres si vous souhaitez restaurer deux fois le répertoire, vous pouvez effectuer une boucle.

dirname(dirname($_SERVER['PHP_SELF']))

dirname est une fonction pour obtenir le site Web parent addrest et $ _SERVER ['PHP_SELF'] peut afficher le site Web en cours.

thakyou Monsieur https://stackoverflow.com/users/171318/hek2mgl

Je ne suggère pas d'utiliser dirname() comme c'est le cas pour les répertoires et non pour les URI. Exemples:

  • dirname("http://example.com/foo/index.php") renvoie http://example.com/foo
  • dirname("http://example.com/foo/") renvoie http://example.com
  • dirname("http://example.com/") renvoie http:
  • dirname("http://example.com") renvoie http:

Donc, vous devez savoir très bien quel $_SERVER var vous utilisez et, bien sûr, cela ne fonctionne que pour ce problème spécifique. Une meilleure solution générale consisterait à utiliser currentdir () sur cette base, vous pourriez l'utiliser pour obtenir le répertoire parent:

function parentdir($url) {
    // note: parent of "/" is "/" and parent of "http://example.com" is "http://example.com/"
    // remove filename and query
    $url = currentdir($url);
    // get parent
    $len = strlen($url);
    return currentdir(substr($url, 0, $len && $url[ $len - 1 ] == '/' ? -1 : $len));
}

Exemples:

  • parentdir("http://example.com/foo/bar/index.php") renvoie http://example.com/foo/
  • parentdir("http://example.com/foo/index.php") renvoie http://example.com/
  • parentdir("http://example.com/foo/") renvoie http://example.com/
  • parentdir("http://example.com/") renvoie http://example.com/
  • parentdir("http://example.com") renvoie http://example.com/

Donc, vous auriez des résultats beaucoup plus stables. Peut-être pourriez-vous expliquer pourquoi vous vouliez supprimer la barre oblique finale. D'après mon expérience, cela pose plus de problèmes car vous ne pouvez pas différencier un fichier nommé "/ foo" d'un dossier du même nom sans utiliser is_dir(). Mais si cela est important pour vous, vous pouvez supprimer le dernier caractère .

1
mgutt

Cet exemple fonctionne avec les ports

function full_url($s)
{
    $ssl = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on') ? true:false;
    $sp = strtolower($s['SERVER_PROTOCOL']);
    $protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
    $port = $s['SERVER_PORT'];
    $port = ((!$ssl && $port=='80') || ($ssl && $port=='443')) ? '' : ':'.$port;
    $Host = isset($s['HTTP_Host']) ? $s['HTTP_Host'] : $s['SERVER_NAME'];
    return $protocol . '://' . $Host . $port . $s['REQUEST_URI'];
}
$themeurl = dirname(dirname(full_url($_SERVER))).'/theme';
echo '<a href="'.htmlspecialchars($themeurl,ENT_QUOTES,'UTF-8').'">Theme URL</a>';

Source: https://stackoverflow.com/a/8891890/175071

1
Timo Huovinen

Je suis avec hek2mgl. Cependant, juste au cas où le script ne soit pas toujours spécifiquement 2 répertoires sous votre cible, vous pouvez utiliser exploser:

$parts = explode("/",ltrim($_SERVER['SCRIPT_NAME'],"/"));
echo $_SERVER['HTTP_Host'] . "/" . $parts[0];
0
George

Comme hek2mgl l'a mentionné, c'est correct et une approche plus dynamique serait dirname(dirname(htmlspecialchars($_SERVER['REQUEST_URI'])));.

MODIFIER:

$ _SERVER ['REQUEST_URI'] omettra le nom de domaine. En se référant au message de @ hek2mgl, vous pouvez echo dirname(dirname(htmlspecialchars($url)));

0
Sid