如何在2个以上的目录中包含文件?


93

如何包含超过2个目录的文件。我知道您可以使用../index.php包含后2个目录的文件,但是您如何使用后3个目录呢?这有意义吗?我试过了,.../index.php但是没有用。

我有一个文件,/game/forum/files/index.php它使用PHP include包含一个文件。位于/includes/boot.inc.php; /是根目录。


1
它更像PHP,而不是HTML ...
kender

chdir(''../'');
maheshmnj

Answers:


152

..从当前目录中选择父目录。当然,可以将其链接起来:

../../index.php

这将是两个目录。


1
@Brian好吧,这是胡说八道,您正在比较苹果和桔子。没错,define这里将使用a,但(1)甚至不是这里的问题。并且(2)仍然会在您的define服务器中使用相对路径,除非您实际上对整个绝对服务器路径进行了硬编码,但我会避免这样做,因为它只有缺点。或者(第三个选择),您可以使用字符串操作从(扩展的)当前路径中提取父目录,但是再次使用相对路径没有任何优势。
康拉德·鲁道夫2012年

可悲的是这可以在一个设备上工作,而不是另一个,/../可能工作或者../可能工作,或者两者都不是可以在三个不同的计算机上工作具有完全相同的环境设置
道格拉斯·加斯克尔

@DouglasGaskell不,那是不正确的。相对路径符号(包括../和)../../(注意:不能使用斜杠!)在所有现代操作系统上均适用。它曾经不能在Windows和(很久以前)Macintosh上运行,但现在在任何地方都可以运行,并且至少已经运行了十年。如果在某处不起作用,则原因是文件结构不同,和/或您位于其他工作目录中。但这与这段代码无关。
康拉德·鲁道夫

Konrad,我之所以提到这一点,是因为我不是在10分钟前使用虚拟机快照与同事共享存储库后才处理此问题。由于某种原因,必须走所有的路,/../而不是../依靠他的环境。
道格拉斯·加斯凯尔

@DouglasGaskell而且我可以自信地告诉您该错误无关。实际上,该路径/../在任何系统上都毫无意义(等效于/,或者是错误)。您确定没有在其前面粘贴内容吗?
康拉德·鲁道夫

51

要将文件包含在一个目录中,请使用'../file'。对于两个目录,请使用'../../file'。等等。

尽管实际上,您不应该执行相对于当前目录的包含。如果要移动该文件怎么办?所有链接都将断开。确保您仍然可以链接到其他文件,同时在移动文件时保留这些链接的一种方法是:

require_once($_SERVER['DOCUMENT_ROOT'] . 'directory/directory/file');

DOCUMENT_ROOT 是一个服务器变量,代表您的代码所在的基本目录。


2
嘿,丹快速问:您说“ 实际上,您不应该执行相对于当前目录的包含 ”。在大多数HTML文档中乱七八糟的所有相对路径如何?如果我移动了文件,这些文件也不会损坏吗?是否存在何时使用相对链接和绝对链接的标准?先感谢您!
Govind Rai

2
我认为它缺少一个斜杠,应该是:require_once($ _ SERVER ['DOCUMENT_ROOT']。'/ directory / directory / file');
user889030

据我所知,@ user889030至少在大多数情况下都不需要斜杠
BotMaster3000 '18


27
. = current directory
.. = parent directory

因此,../使您返回一个目录而不是两个目录

../多次必要去了2倍或以上的水平。


21
include dirname(__FILE__).'/../../index.php';

是您最好的选择,它将避免其他解决方案可能遇到的大多数相对路径错误。

确实,这将迫使include始终相对于放置此代码的当前脚本的位置(该位置很可能是稳定的,因为您定义了应用程序的体系结构)。这与仅执行include '../../index.php' 相对于执行(也称为“调用”)脚本,然后相对于当前工作目录(仅指向包含您的脚本的父脚本)有关,而不是从包含的脚本路径进行解析。

从PHP文档中:

根据给定的文件路径包含文件,如果没有给出文件路径,则基于指定的include_path。如果在include_path中找不到该文件,则include最终将在失败之前检入调用脚本的自身目录和当前工作目录。

我发现引用此技巧的最古老的帖子可以追溯到Tapken的2003年

您可以使用以下设置进行测试:

创建这样的布局:

htdocs
¦   parent.php
¦   goal.php
¦
+---sub
    ¦   included.php
    ¦   goal.php

在中parent.php,输入:

<?php
include dirname(__FILE__).'/sub/included.php';
?>

在中sub/included.php,输入:

<?php
print("WRONG : " . realpath('goal.php'));
print("GOOD : " . realpath(dirname(__FILE__).'/goal.php'));
?>

访问结果parent.php

WRONG : X:\htdocs\goal.php
GOOD : X:\htdocs\sub\goal.php

如我们所见,在第一种情况下,路径是从调用脚本解析的parent.php,而通过使用dirname(__FILE__).'/path'技巧,包含是从included.php放置代码的脚本完成的。

当心,以下内容与上面的技巧并不等同,与其他地方可以读到的相反:

include '/../../index.php';

的确,前置/可以起作用,但是可以像include ../../index.php调用脚本一样进行解析(不同之处在于,include_path如果失败,它将不会在以后被查看)。从PHP doc

如果定义了路径(无论是绝对路径(在Windows中以驱动器号或\开头,在Unix / Linux系统上以/开头)还是相对于当前目录(以。或..开头),则include_path将被完全忽略。


@diEcho:我可以知道为什么它“完全错误”吗?我在几个专业级应用程序上使用它,而该方法实际上是在每种情况下都可以使用的唯一方法。在php手册中也有详细说明 :不会错。
华丽的

第一行是完全错误的。您不能添加..路径的中间(相对/绝对)。
diEcho 2012年


告诉我一个示例,在..包含中间使用何处。它始终应该是include的第一部分
diEcho 2012年

github.com/lrq3000/dolibarr_customfields/blob/3.2/htdocs/…用于专业级ERP / CRM的专业级模块。先生,当您不知道说什么时,您不应该讲话。
华丽的2012年

16

../是一个目录,重复两个目录../../,甚至三个:../../../等等。

定义常量可以减少混乱,因为您将向后钻入目录

您可以这样定义一些常量:

define('BD', '/home/user/public_html/example/');

define('HTMLBD', 'http://example.com/');

当使用“ BD”或我的“基本目录”时,它看起来像这样:

file(BD.'location/of/file.php');

define(); 参考



12
../../../includes/boot.inc.php

每个实例../意味着向上/向后一个目录。


9

以下是访问您的不同目录的方法:-

./ = Your current directory
../ = One directory lower
../../ = Two directories lower
../../../ = Three directories lower

7

您可以../../directory/file.txt-将两个目录退回。

../../../-这三个。等等



6

但是要非常小心让用户选择文件。您并不是真的想让他们获得一个名为的文件,例如,

../../../../../../../../../../etc/passwd

或其他敏感的系统文件。

(对不起,自从我是linux sysadmin以来已经有一段时间了,根据我的记忆,我认为这是一个敏感文件)




4

如果您使用的是php7,则可以使用级别参数为2的dirname函数,例如:

dirname("/usr/local/lib", 2);

第二个参数“ 2”表示升级多少

目录名引用


3

可以通过代理文件处理包括目录在内的所有内容

  • ..... | __web
  • ..... | ......... | __requiredDbSettings.php
  • ..... |
  • ..... | ____ db
  • ..... | ......... | __dbsettings.php
  • ..... |
  • ..... | __proxy.php

    dbsettings.php:
    $host='localhost';
    $user='username':
    $pass='pass';
    
    proxy.php:
    include_once 'db/dbsettings.php
    
    requiredDbSettings.php:
    include_once './../proxy.php';

2

尝试../../。您可以进行相应的修改,因为它将带您回到两个目录。首先进入根目录,然后访问所需目录。

例如,您在其中,root/inc/usr/ap并且还有另一个目录root/2nd/path。您可以通过以下方式访问path目录ap../../2nd/path首先进入所需目录的根目录。如果不起作用,请分享。


2

如果您在包含内容的/开头包含,则包含内容将作为从站点根目录开始的路径。

如果您的网站是http://www.example.com/game/forum/files/index.php,则可以在/includes/boot.inc.php中添加一个包含内容的内容,该内容将解析为http://www.example.com /includes/boot.inc.php

..由于某些Web服务器已禁用遍历,因此必须小心。当您要将站点移至新的计算机/主机时,它还会引起问题,并且结构有所不同。


2

试试这个

这个例子是一个目录

require_once('../images/yourimg.png');

这个例子是两个目录

require_once('../../images/yourimg.png');

这是完全一样的;-)我想你的意思是第二个是“ ../../images/yourimg.png”吗?
艾德温

冒犯了我的错误
rajpoot rehan '19

1

我看到了您的答案,并使用了包含语法的路径

require_once '../file.php'; // server internal error 500

和http服务器(Apache 2.4.3)返回内部错误500。

当我将路径更改为

require_once '/../file.php'; // OK

一切都很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.