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

时间:2013-02-27 10:59:19

标签: php url path

我正在使用:

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

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

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

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

例子: 如果给出:

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

需要:

https://stackoverflow.com/questions

没有斜线。

也应该说:

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

获取

http://localhost/GetSimple

这就是我要做的事。

谢谢。

<小时/> <小时/> 修改 这是我使用的工作解决方案:

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

效果很好。

7 个答案:

答案 0 :(得分:32)

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

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

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

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

echo dirname(dirname($url));

答案 1 :(得分:2)

我有更简单的语法来获取带有port和url的父addres 让我们试试我的代码

dirname($_SERVER['PHP_SELF'])

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

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

dirname用于获取父级addrest web,$ _SERVER ['PHP_SELF']可以显示当前的addres web。

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

答案 2 :(得分:1)

此示例适用于端口

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>';

来源:https://stackoverflow.com/a/8891890/175071

答案 3 :(得分:1)

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

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

所以你必须非常小心,你使用$_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));
}

实例:

  • 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/

所以你会有更稳定的结果。也许您可以解释为什么要删除尾部斜杠。我的经验是它产生了更多的问题,因为你无法区分名为&#34; / foo&#34;的文件。以及不使用is_dir()的同名文件夹。但如果这对你很重要,你可以remove the last char

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

正如hek2mgl所说,这是正确的,更动态的方法是dirname(dirname(htmlspecialchars($_SERVER['REQUEST_URI'])));

编辑:

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

答案 6 :(得分:-2)

以下是获取所需路径的有用命令:

(例如,您正在 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

示例:

*主页网址( yoursite.com )

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

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

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

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

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

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

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

*获取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 ,已经有预先定义的函数来获取插件或主题网址。

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