如何安全地获取当前 PHP 页面的父目录的完整 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15110355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to safely get full URL of parent directory of current PHP page
提问by Rocket Spaceman
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”之外的任何东西都有这样的风险..不确定虽然ofc..只是一直在阅读大量试图弄清楚这一点。
examples: if given:
示例:如果给出:
https://stackoverflow.com/questions/somequestions/index.php
need:
需要:
https://stackoverflow.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:编辑:这是我使用的工作解决方案:
$url = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$url .= $_SERVER['SERVER_NAME'];
$url .= htmlspecialchars($_SERVER['REQUEST_URI']);
$themeurl = dirname(dirname($url)) . "/theme";
it works perfectly.
它完美地工作。
回答by hek2mgl
Thats easy - using the function dirnametwice :)
这很简单 - 使用该功能dirname两次:)
echo dirname(dirname('https://stackoverflow.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));
回答by Dienastya Galih Pradana
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 是获取父地址 web 的功能,$_SERVER['PHP_SELF'] 可以显示当前地址 web。
thakyou Sir https://stackoverflow.com/users/171318/hek2mgl
回答by mgutt
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")returnshttp://example.com/foodirname("http://example.com/foo/")returnshttp://example.comdirname("http://example.com/")returnshttp:dirname("http://example.com")returnshttp:
dirname("http://example.com/foo/index.php")返回http://example.com/foodirname("http://example.com/foo/")返回http://example.comdirname("http://example.com/")返回http:dirname("http://example.com")返回http:
So you have to be very carful which $_SERVERvar 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")returnshttp://example.com/foo/parentdir("http://example.com/foo/index.php")returnshttp://example.com/parentdir("http://example.com/foo/")returnshttp://example.com/parentdir("http://example.com/")returnshttp://example.com/parentdir("http://example.com")returnshttp://example.com/
parentdir("http://example.com/foo/bar/index.php")返回http://example.com/foo/parentdir("http://example.com/foo/index.php")返回http://example.com/parentdir("http://example.com/foo/")返回http://example.com/parentdir("http://example.com/")返回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.
所以你会有更稳定的结果。也许您可以解释为什么要删除尾部斜杠。我的经验是它会产生更多问题,因为您无法区分名为“/foo”的文件和不使用is_dir(). 但如果这对您很重要,您可以删除最后一个 char。
回答by Timo Huovinen
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>';
回答by George
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 个目录,您可以使用爆炸:
$parts = explode("/",ltrim($_SERVER['SCRIPT_NAME'],"/"));
echo $_SERVER['HTTP_HOST'] . "/" . $parts[0];
回答by Sid
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 的帖子,你可以echo dirname(dirname(htmlspecialchars($url)));
回答by T.Todua
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 )
*首页网址 ( yoursite.com )
<?php echo $_SERVER['HTTP_HOST'];?>
*file's BASE url ( yoursite.com/anyfolder/myfile.php )
*文件的基础网址 ( 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/ )
*当前文件夹的 URL ( 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.
psfor wordpress,已经存在预定义的函数来获取插件或主题 url。
i.e. get plugin folder ( http://yoursite.com/wp-content/plugins/pluginName/ )
<?php echo plugin_dir_url( __FILE__ );?>

