如何安全地获取当前PHP页面的父目录的完整URL

时间:2021-08-02 23:44:14

I'm using:

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

But this of course gives the full URL. Instead I need the full URL minus the current file and up one directory and minus the trailing slash.

但这当然会提供完整的URL。相反,我需要完整的URL减去当前文件和一个目录并减去尾部斜杠。

so no matter what the browser URL domain is eg localhost, https://, http://, etc that the full real (bypassing any mod rewrites) URL path of the parent directory is given without a trailing slash.

因此,无论浏览器URL域是什么,例如localhost,https://,http://等,都会给出父目录的完整实际(绕过任何mod重写)URL路径而不带尾部斜杠。

How is this done? Safely so no XSS as I guess (from reading) using anything but 'SCRIPT_NAME' has such risk.. not sure though ofc.. just been reading a ton trying to figure this out.

这是怎么做到的?安全所以没有XSS,因为我猜(从阅读中)使用“SCRIPT_NAME”之类的任何东西都有这样的风险..虽然不确定但是...只是读了很多试图解决这个问题。

examples: if given:

例子:如果给出:

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

need:

https://*.com/questions

without the trailing slash.

没有尾随斜线。

and should also work for say:

也应该说:

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

to get

http://localhost/GetSimple

which is what I'm trying to do.

这就是我想要做的。

Thank you.



Edit: Here's the working solution I used:

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

it works perfectly.

它完美地运作。

7 个解决方案

#1


30  

Thats easy - using the function dirname twice :)

多么容易 - 使用函数dirname两次:)

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

Also note @Sid's comment. When you you need the full uri to the current script, with protocol and server the use something like this:

另请注意@Sid的评论。如果您需要完整的uri到当前脚本,使用协议和服务器,请使用以下内容:

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

echo dirname(dirname($url));

#2


2  

I have more simple syntax to get parent addres with port and url lets try my code

我有更简单的语法来获取带端口和url的父地址让我们尝试我的代码

dirname($_SERVER['PHP_SELF'])

with this code you can got a direct parent of adres if you want to 2x roll back directory you can looping

如果您想要2x回滚目录,您可以使用此代码获得adres的直接父级

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

dirname is fungtion to get parent addrest web and $_SERVER['PHP_SELF'] can showing current addres web.

dirname是获取父addrest web的真假,$ _SERVER ['PHP_SELF']可以显示当前的addres web。

thakyou Sir https://*.com/users/171318/hek2mgl

thakyou Sir https://*.com/users/171318/hek2mgl

#3


1  

This example works with 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://*.com/a/8891890/175071

#4


1  

I do not suggest using dirname()as it is for directories and not for URIs. Examples:

我不建议使用dirname(),因为它是目录而不是URI。例子:

  • dirname("http://example.com/foo/index.php") returns http://example.com/foo
  • dirname(“http://example.com/foo/index.php”)返回http://example.com/foo

  • dirname("http://example.com/foo/") returns http://example.com
  • dirname(“http://example.com/foo/”)返回http://example.com

  • dirname("http://example.com/") returns http:
  • dirname(“http://example.com/”)返回http:

  • dirname("http://example.com") returns http:
  • dirname(“http://example.com”)返回http:

So you have to be very carful which $_SERVER var you use and of course it works only for this specific problem. A much better general solution would be to use currentdir() on which basis you could use this to get the parent directory:

所以你必须非常小心你使用$ _SERVER var,当然它只适用于这个特定的问题。一个更好的通用解决方案是使用currentdir(),您可以使用它来获取父目录:

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

Examples:

  • parentdir("http://example.com/foo/bar/index.php") returns http://example.com/foo/
  • parentdir(“http://example.com/foo/bar/index.php”)返回http://example.com/foo/

  • parentdir("http://example.com/foo/index.php") returns http://example.com/
  • parentdir(“http://example.com/foo/index.php”)返回http://example.com/

  • parentdir("http://example.com/foo/") returns http://example.com/
  • parentdir(“http://example.com/foo/”)返回http://example.com/

  • parentdir("http://example.com/") returns http://example.com/
  • parentdir(“http://example.com/”)返回http://example.com/

  • parentdir("http://example.com") returns http://example.com/
  • parentdir(“http://example.com”)返回http://example.com/

So you would have much more stable results. Maybe you could explain why you wanted to remove the trailing slash. My experience is that it produces more problems as you are not able to differentiate between a file named "/foo" and a folder with the same name without using is_dir(). But if this is important for you, you could remove the last char.

所以你会得到更稳定的结果。也许你可以解释为什么要删除尾部斜杠。我的经验是它会产生更多问题,因为如果不使用is_dir(),就无法区分名为“/ foo”的文件和具有相同名称的文件夹。但如果这对你很重要,你可以删除最后一个字符。

#5


0  

I'm with hek2mgl. However, just in case the script isn't always specifically 2 directories below your target, you could use explode:

我和hek2mgl。但是,如果脚本并不总是特定于目标下面的2个目录,则可以使用explode:

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

#6


0  

As hek2mgl mentioned, it's correct, and a more dynamic approach would be dirname(dirname(htmlspecialchars($_SERVER['REQUEST_URI'])));.

正如hek2mgl提到的,它是正确的,更动态的方法是dirname(dirname(htmlspecialchars($ _ SERVER ['REQUEST_URI'])));.

EDIT:

$_SERVER['REQUEST_URI'] will omit the domain name. Referring @hek2mgl's post, you can echo dirname(dirname(htmlspecialchars($url)));

$ _SERVER ['REQUEST_URI']将省略域名。参考@ hek2mgl的帖子,你可以回复dirname(dirname(htmlspecialchars($ url)));

#7


-2  

Here are useful commands to get the desired path:

( For example, you are executing in http:// yoursite.com/folder1/folder2/file.php)

(例如,您正在http:// yoursite.com/folder1/folder2/file.php中执行)

__FILE__   (on L.Hosting)   === /home/xfiddlec/http_docs/folder1/folder2/yourfile.php
__FILE__   (on Localhost) === C:\wamp\www\folder1\folder2\yourfile.php 
$_SERVER['HTTP_HOST']     === www.yoursite.com (or without WWW)   
$_SERVER["PHP_SELF"]      === /folder1/folder2/yourfile.php
$_SERVER["REQUEST_URI"]   === /folder1/folder2/yourfile.php?var=blabla
$_SERVER["DOCUMENT_ROOT"] === /home/xfiddlec/http_docs

// BASENAME and DIRNAME (lets say,when __file__ is '/folder1/folder2/yourfile.php'
basename(__FILE__)  ==== yourfile.php
dirname(__FILE__)   ==== /folder1/folder2

Examples:

*HOME url             ( yoursite.com )

* HOME url(yoursite.com)

<?php echo $_SERVER['HTTP_HOST'];?>

*file's BASE url     ( yoursite.com/anyfolder/myfile.php )

*文件的BASE网址(yoursite.com/anyfolder/myfile.php)

<?php echo $_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; ?>

*COMPLETE current url ( yoursite.com/anyfolder/myfile.php?action=blabla )

*完整的当前网址(yoursite.com/anyfolder/myfile.php?action=blabla)

<?php echo $_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"];?>

*CURRENT FOLDER's URL ( yoursite.com/anyfolder/ )

* CURRENT FOLDER的网址(yoursite.com/anyfolder/)

<?php echo $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']);  ?>

*To get RealPath to the file (even if it is included) (change /var/public_html to your desired root)

*获取RealPath到文件(即使它包含在内)(将/ var / public_html更改为所需的根目录)

<?php
$cur_file=str_replace('\\','/',__FILE__); //Then Remove the root path::
$cur_file=preg_replace('/(.*?)\/var\/public_html/','',$cur_file);
?>

p.s.for wordpress, there exist already pre-defined functions to get plugins or themes url.

p.s.for wordpress,已经有预定义的函数来获取插件或主题url。

i.e. get plugin folder ( http://yoursite.com/wp-content/plugins/pluginName/ )
<?php echo plugin_dir_url( __FILE__ );?>

#1


30  

Thats easy - using the function dirname twice :)

多么容易 - 使用函数dirname两次:)

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

Also note @Sid's comment. When you you need the full uri to the current script, with protocol and server the use something like this:

另请注意@Sid的评论。如果您需要完整的uri到当前脚本,使用协议和服务器,请使用以下内容:

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

echo dirname(dirname($url));

#2


2  

I have more simple syntax to get parent addres with port and url lets try my code

我有更简单的语法来获取带端口和url的父地址让我们尝试我的代码

dirname($_SERVER['PHP_SELF'])

with this code you can got a direct parent of adres if you want to 2x roll back directory you can looping

如果您想要2x回滚目录,您可以使用此代码获得adres的直接父级

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

dirname is fungtion to get parent addrest web and $_SERVER['PHP_SELF'] can showing current addres web.

dirname是获取父addrest web的真假,$ _SERVER ['PHP_SELF']可以显示当前的addres web。

thakyou Sir https://*.com/users/171318/hek2mgl

thakyou Sir https://*.com/users/171318/hek2mgl

#3


1  

This example works with 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://*.com/a/8891890/175071

#4


1  

I do not suggest using dirname()as it is for directories and not for URIs. Examples:

我不建议使用dirname(),因为它是目录而不是URI。例子:

  • dirname("http://example.com/foo/index.php") returns http://example.com/foo
  • dirname(“http://example.com/foo/index.php”)返回http://example.com/foo

  • dirname("http://example.com/foo/") returns http://example.com
  • dirname(“http://example.com/foo/”)返回http://example.com

  • dirname("http://example.com/") returns http:
  • dirname(“http://example.com/”)返回http:

  • dirname("http://example.com") returns http:
  • dirname(“http://example.com”)返回http:

So you have to be very carful which $_SERVER var you use and of course it works only for this specific problem. A much better general solution would be to use currentdir() on which basis you could use this to get the parent directory:

所以你必须非常小心你使用$ _SERVER var,当然它只适用于这个特定的问题。一个更好的通用解决方案是使用currentdir(),您可以使用它来获取父目录:

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

Examples:

  • parentdir("http://example.com/foo/bar/index.php") returns http://example.com/foo/
  • parentdir(“http://example.com/foo/bar/index.php”)返回http://example.com/foo/

  • parentdir("http://example.com/foo/index.php") returns http://example.com/
  • parentdir(“http://example.com/foo/index.php”)返回http://example.com/

  • parentdir("http://example.com/foo/") returns http://example.com/
  • parentdir(“http://example.com/foo/”)返回http://example.com/

  • parentdir("http://example.com/") returns http://example.com/
  • parentdir(“http://example.com/”)返回http://example.com/

  • parentdir("http://example.com") returns http://example.com/
  • parentdir(“http://example.com”)返回http://example.com/

So you would have much more stable results. Maybe you could explain why you wanted to remove the trailing slash. My experience is that it produces more problems as you are not able to differentiate between a file named "/foo" and a folder with the same name without using is_dir(). But if this is important for you, you could remove the last char.

所以你会得到更稳定的结果。也许你可以解释为什么要删除尾部斜杠。我的经验是它会产生更多问题,因为如果不使用is_dir(),就无法区分名为“/ foo”的文件和具有相同名称的文件夹。但如果这对你很重要,你可以删除最后一个字符。

#5


0  

I'm with hek2mgl. However, just in case the script isn't always specifically 2 directories below your target, you could use explode:

我和hek2mgl。但是,如果脚本并不总是特定于目标下面的2个目录,则可以使用explode:

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

#6


0  

As hek2mgl mentioned, it's correct, and a more dynamic approach would be dirname(dirname(htmlspecialchars($_SERVER['REQUEST_URI'])));.

正如hek2mgl提到的,它是正确的,更动态的方法是dirname(dirname(htmlspecialchars($ _ SERVER ['REQUEST_URI'])));.

EDIT:

$_SERVER['REQUEST_URI'] will omit the domain name. Referring @hek2mgl's post, you can echo dirname(dirname(htmlspecialchars($url)));

$ _SERVER ['REQUEST_URI']将省略域名。参考@ hek2mgl的帖子,你可以回复dirname(dirname(htmlspecialchars($ url)));

#7


-2  

Here are useful commands to get the desired path:

( For example, you are executing in http:// yoursite.com/folder1/folder2/file.php)

(例如,您正在http:// yoursite.com/folder1/folder2/file.php中执行)

__FILE__   (on L.Hosting)   === /home/xfiddlec/http_docs/folder1/folder2/yourfile.php
__FILE__   (on Localhost) === C:\wamp\www\folder1\folder2\yourfile.php 
$_SERVER['HTTP_HOST']     === www.yoursite.com (or without WWW)   
$_SERVER["PHP_SELF"]      === /folder1/folder2/yourfile.php
$_SERVER["REQUEST_URI"]   === /folder1/folder2/yourfile.php?var=blabla
$_SERVER["DOCUMENT_ROOT"] === /home/xfiddlec/http_docs

// BASENAME and DIRNAME (lets say,when __file__ is '/folder1/folder2/yourfile.php'
basename(__FILE__)  ==== yourfile.php
dirname(__FILE__)   ==== /folder1/folder2

Examples:

*HOME url             ( yoursite.com )

* HOME url(yoursite.com)

<?php echo $_SERVER['HTTP_HOST'];?>

*file's BASE url     ( yoursite.com/anyfolder/myfile.php )

*文件的BASE网址(yoursite.com/anyfolder/myfile.php)

<?php echo $_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; ?>

*COMPLETE current url ( yoursite.com/anyfolder/myfile.php?action=blabla )

*完整的当前网址(yoursite.com/anyfolder/myfile.php?action=blabla)

<?php echo $_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"];?>

*CURRENT FOLDER's URL ( yoursite.com/anyfolder/ )

* CURRENT FOLDER的网址(yoursite.com/anyfolder/)

<?php echo $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']);  ?>

*To get RealPath to the file (even if it is included) (change /var/public_html to your desired root)

*获取RealPath到文件(即使它包含在内)(将/ var / public_html更改为所需的根目录)

<?php
$cur_file=str_replace('\\','/',__FILE__); //Then Remove the root path::
$cur_file=preg_replace('/(.*?)\/var\/public_html/','',$cur_file);
?>

p.s.for wordpress, there exist already pre-defined functions to get plugins or themes url.

p.s.for wordpress,已经有预定义的函数来获取插件或主题url。

i.e. get plugin folder ( http://yoursite.com/wp-content/plugins/pluginName/ )
<?php echo plugin_dir_url( __FILE__ );?>