【问题标题】:How to refer back to public_html root file using include after going up one file directory out of public_html从public_html上上一个文件目录后如何使用include返回public_html根文件
【发布时间】:2012-07-08 04:43:24
【问题描述】:

根据一些非常有用的提示,我正在使用以下代码在我的根目录之外包含PHP 文件,看起来与此类似:

define('WEB_ROOT', __DIR__);
define('APP_ROOT', dirname(__DIR__));
define('PHP_ROOT', APP_ROOT . DIRECTORY_SEPARATOR . 'application');


include(PHP_ROOT . DIRECTORY_SEPARATOR . 'bootstrap.php');

我的问题是,例如,您可以根据上面的内容包含代码bootstrap.php

如果 PHP 文件引导程序有自己的代码行,在 public_html 根文件夹中包含一个文件 BACK 怎么办......如何编写代码?我在这样做时遇到了一些困难,我的目标是我不想将实际的文字目录完整地放入代码中,并且我想避免文件遍历攻击

【问题讨论】:

  • 如果您不想使用绝对路径,一种方法是在“外部”脚本中定义一个变量,然后在包含的“内部脚本”中使用该变量。例如:外部脚本中的$include_prefix = <something>; 和bootstrap.php 中的if(isset('include_prefix')){ include($include_prefix . "<something>"); }。但是,如果安全性和可靠性受到任何严重关注,我认为绝对路径是最好的方法。
  • 哦,对不起,我应该澄清一下我认为我遇到的麻烦是,而不是简单地能够去 include("thatfilebackinrootdirectory.php");例如,它正在工作......它给了我一个错误,说没有这样的文件或目录,我假设因为我已经从根目录中上去了一个目录,它现在不知道如何从它在哪里?
  • 您对出现该错误的原因是正确的。有很多解决方案——我会在一秒钟内详细回答。

标签: php security include root


【解决方案1】:

考虑这个项目结构:

/path/to/projectroot/index.php 头文件.php 包括/inc.php

如果 index.php 有

include('include/inc.php');

和inc.php有

include('header.php');

你会得到那个错误,因为 inc.php 中的行正在寻找

/path/to/projectroot/include/header.php(不存在)

不是

/path/to/projectroot/header.php(确实存在)

人们有几种方法可以解决这个问题。

1:绝对路径

第一个也是最直接的方法是使用绝对路径。

如果 index.php 有

include('include/inc.php');

和inc.php有

include('/path/to/projectroot/header.php');

这会起作用。

2:带定义的绝对路径

类似于 #1,如果 index.php 有

define('PROJECT_ROOT', '/path/to/projectroot/');
include(PROJECT_ROOT.'include/inc.php');

和inc.php有

include(PROJECT_ROOT.'header.php');

这会起作用。

更新:正如 pichan 在 cmets 中所述,您可以在 index.php 中使用 "magic" constants 之一,因此:

index.php

define('PROJECT_ROOT', __DIR__.'/');
include(PROJECT_ROOT.'include/inc.php');

和inc.php

include(PROJECT_ROOT.'header.php');

请注意,我们在__DIR__ 后面添加一个斜杠,因为:

除非是根目录,否则此目录名称没有尾部斜杠。

3:同时包含并隐藏错误

如果 inc.php 有

@include('header.php');    # Try this directory
@include('../header.php'); # Try parent directory

这会起作用。[1]

4:除非另有说明,否则假定为当前目录

如果 index.php 有

$rel_prefix_to_root = '../';
include('include/inc.php');

和inc.php有

if(!isset($rel_path_to_root)){ $rel_path_to_root = ''; }
include($rel_path_to_root . 'header.php');

这会起作用。

我对这些方法的看法

1 和 2 基本相同,但 2 对于大型项目来说更容易和更常见,因为它允许您进行一个常量定义并在站点范围内使用它。它还允许您将项目部署在多个服务器上(放置在多个路径中),并且只需要在项目范围内更改一行,而不是选项 1 的每个文件中的一行。

3 太可怕了,不要这样做。有时您会看到它,您甚至可能会在在线教程中看到它。不要这样做。

应该避免使用 4 来支持 1 或 2。但如果您有一些复杂的包含集,则这种方法可能是必要的。

一些注意事项:

[1] 这是一个糟糕的主意。它有效,但不要这样做。

【讨论】:

  • 那么@jedwards 你的意思是 4 种方法中的示例 1 是所有 4 种解决方案中最不受欢迎的吗?
  • @Kalcoder:我会说 3 是最不受欢迎的。 1 通常用于较小的项目,并且可以完美运行(前提是路径正确)。 2 比 1 更容易维护,但它们在功能上是相同的。
  • @jedwards 我想对 #2 提出改进建议:您可以在 index.php 中使用 define('PROJECT_ROOT', dirname(__FILE__)); //or just __DIR__ 代替硬编码路径。我敢肯定你已经知道这一点,但应该更多地宣传这一点,特别是因为你的答案是公认的:)
【解决方案2】:

要获取 public_html 上面的目录,我使用以下
$aboveRoot = explode('/public_html', $_SERVER['DOCUMENT_ROOT']);
定义('ABOVE_THE_ROOT', $aboveRoot[0]);

【讨论】:

  • 我接受这是一个糟糕/糟糕的答案。我只是想知道为什么?
  • 嗯,我总是很好奇,而且思想开放。我想每个人都会从我猜的答案中受益。 @George,我在做什么这个......我是public_html,我向上,我进入另一个文件夹,让我们称这个文件夹为batman,我进入batman,然后我想在public_html中包含一个文件,所以不知何故,我需要回到 public_html 而不冒任何安全漏洞的风险,这将使某人能够以任何方式进行文件遍历或破解它
  • 实际上也是@George,我认为他可能指的是他给出的示例编号 1(共 4 个),并说他自己帖子中的选项 1 可能不是给出的 4 个示例中最好的,所以请继续发布答案,以任何形式分享知识都是好的:)
猜你喜欢
  • 2015-09-05
  • 2016-04-30
  • 2021-12-05
  • 2013-04-21
  • 1970-01-01
  • 2011-10-08
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多