如何包含需要绝对路径的PHP文件?

99
我有以下的目录结构:

script.php

inc/include1.php
inc/include2.php

objects/object1.php
objects/object2.php

soap/soap.php

现在,我在script.php/soap/soap.php中都使用这些对象。虽然我可以移动它们,但是出于特定原因,我想保留该目录结构。当执行script.php时,包含路径为inc/include.php,而当执行/soap/soap.php时,则为../inc。绝对路径可行,如/mnt/webdev/[项目名称]/inc/include1.php...,但如果我将目录移动到其他位置,这将是一个不好看的解决方案。
那么,有没有一种方法可以使用相对路径或以编程方式生成"/mnt/webdev/[项目名称]/"呢?
11个回答

156

这应该可以工作

$root = realpath($_SERVER["DOCUMENT_ROOT"]);

include "$root/inc/include1.php";

编辑: 加入了由aussieviking提供的改进。


4
请注意,只有通过填充DOCUMENT_ROOT的Web服务器执行脚本时,此方法才能正常工作。 - Phil
只是一个问题,为什么要使用realpath()来获取$_SERVER["DOCUMENT_ROOT"]的路径?这不应该总是输出规范路径吗? - João Pimentel Ferreira

46
你可以使用相对路径。尝试使用__FILE__。这是一个PHP常量,它始终返回所在脚本的路径/文件名。所以,在soap.php中,你可以这样做:
include dirname(__FILE__).'/../inc/include.php';

文件的完整路径和文件名。如果在include中使用,返回的是被包含文件的名称。自从PHP 4.0.2版本以来,__FILE__总是包含一个已解析符号链接的绝对路径,而在旧版本中,在某些情况下它包含相对路径。(source) 另一个解决方案是在httpd.conf或.htaccess文件中设置一个包含路径

8
我认为在引用的表达式开头应该加上一个斜杠 /,以将 ..__FILE__ 名称分开。 - Dunaril
10
请注意,自 PHP 5.3.0 起,您可以使用魔术常量 __DIR__ 来代替使用 dirname(__FILE__)。 (PHP 文档) - Erwin Wessels
4
请勿忘记相对路径前面的斜杠。翻译的内容是:include dirname(__FILE__).'/../inc/include.php'; - Steven Leimberg

6
另一种处理此问题的方法是完全不需要使用includes,而是使用autoload功能。在“Just in Case”情况下包含脚本所需的所有内容可能会影响性能。如果您的includes都是类或接口定义,并且只想在需要时加载它们,那么可以使用自己的代码重载__autoload()函数来查找适当的类文件,并仅在调用时加载它。以下是手册中的示例:
function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2(); 

只要您相应地设置include_path变量,就再也不需要包含类文件了。

6

5

您可以定义一个常量,将其设置为项目根目录的路径,然后将其放置在路径开头。


2
我发现这非常有效!
function findRoot() { 
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

使用:

<?php

function findRoot() {
    return(substr($_SERVER["SCRIPT_FILENAME"], 0, (stripos($_SERVER["SCRIPT_FILENAME"], $_SERVER["SCRIPT_NAME"])+1)));
}

include(findRoot() . 'Post.php');
$posts = getPosts(findRoot() . 'posts_content');

include(findRoot() . 'includes/head.php');

for ($i=(sizeof($posts)-1); 0 <= $i; $i--) {
    $posts[$i]->displayArticle();
}

include(findRoot() . 'includes/footer.php');

?>

2

另一种与Kevin相关的选项是使用__FILE__,但是替换其中的PHP文件名:

<?php

$docRoot = str_replace($_SERVER['SCRIPT_NAME'], '', __FILE__);
require_once($docRoot . '/lib/include.php');

?>

我已经使用这个功能一段时间了。唯一的问题是有时候您没有$_SERVER['SCRIPT_NAME'],但有时会有另一个类似的变量。


1
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/path/to/file.php");

我使用这一行代码。它会返回到站点树的“顶部”,然后转到所需的文件。
例如,假设我有这样的文件树:
domain.com/aaa/index.php domain.com/bbb/ccc/ddd/index.php domain.com/_resources/functions.php 我可以从任何地方包含functions.php文件,只需复制粘贴即可。
require(str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1))."/_resources/functions.php");

如果您需要多次使用此代码,可以创建一个返回 str_repeat('../',(substr_count(getenv('SCRIPT_URL'),'/')-1)) 部分的函数。然后只需将此函数插入到您包含的第一个文件中即可。我有一个名为“initialize.php”的文件,它在每个php页面的最顶部进行包含,并包含此函数。下一次我需要包含文件时,实际上只需使用该函数(名为path_back)即可。
require(path_back()."/_resources/another_php_file.php");

1

我认为最好的方法是将您的包含文件放在PHP包含路径中。根据您的设置,有多种方法可以实现这一点。

然后,您只需引用即可。

require_once 'inc1.php';

无论文件位于包含文件夹还是可访问的网页文件夹中,或者任何嵌套子目录层级中,都可以从内部访问。

这使您可以将包含文件放在 Web 服务器根目录之外,这是最佳实践。

例如:

site directory
    html (web root)
        your web-accessible files
    includes
        your include files

此外,还可以查看 __autoload 以实现类文件的延迟加载。

http://www.google.com/search?q=setting+php+include+path

http://www.google.com/search?q=__autoload


0
如果您的应用程序中的大多数文件都包含特定路径,请创建一个全局变量到您的根文件夹。
define("APPLICATION_PATH", realpath(dirname(__FILE__) . '/../app'));
or 
define("APPLICATION_PATH", realpath(DIR(__FILE__) . '/../app'));

现在这个全局变量 "APPLICATION_PATH" 可以用来包含所有文件,而不是每次包含新文件时都调用 realpath()。
例如:
include(APPLICATION_PATH ."/config/config.ini";

希望它有所帮助;-)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接