在require_once中使用相对路径无法工作

121

我有以下结构

otsg
 > class
   > authentication.php
   > database.php
   > user.php
 > include
   > config.inc.php
   > encryption.php
   > include.php
   > session.php
 > index.php
 > registration.php

include.php文件包含以下内容

ini_set('display_errors', 1);
error_reporting(E_ALL);

ini_set('include_path',ini_get('include_path').':/Applications/MAMP/htdocs/otsg/:');
require_once 'config.inc.php';
require_once '../class/database.php';
require_once '../class/user.php';
require_once 'encryption.php';
require_once 'session.php';
require_once '../class/authentication.php';

而在 index.php 页面中,我已经包含了以下内容

require_once 'include/include.php';

打开index.php页面时,我得到了以下警告和致命错误。我不明白是什么导致了这个错误。当我提供绝对路径时它可以工作。但我认为使用绝对路径不是一个好主意。

Warning: require_once(../class/database.php) [function.require-once]: failed to open stream: No such file or directory in /Applications/MAMP/htdocs/otsg/include/include.php on line 9

Fatal error: require_once() [function.require]: Failed opening required '../class/database.php' (include_path='.:/Applications/MAMP/bin/php5.3/lib/php:/Applications/MAMP/htdocs/otsg/include/:') in /Applications/MAMP/htdocs/otsg/include/include.php on line 9

我通常使用Objective-C,并尝试接触php脚本编程,但很遗憾我已经浪费了2个小时来弄清楚如何在PHP中正确地包含文件。在X-code中这些事情是如此容易。 - rohan-patel
经常会遇到这个错误,为了快速排除故障,请按照以下步骤操作:stackoverflow.com/a/36577021/2873507 - Vic Seedoubleyew
4个回答

252
使用
__DIR__

获取脚本的当前路径,这应该可以解决您的问题。

因此:

require_once(__DIR__.'/../class/user.php');

这将防止您从不同的文件夹运行PHP脚本,因此相对路径将无法正常工作。

编辑:斜杠问题已修复。


43
注意!__DIR__在PHP 5.3中才出现。如果您需要在早期版本的PHP上运行此脚本,则应改用dirname(__FILE__) - Charles
29
请注意,在__DIR__后面需要手动添加尾部斜杠。 因此,代码应该是这样的: require_once(__DIR__.'/../class/user.php');根据文档所述,只有根目录才会包含结尾的斜杠。 - Ariel Allon
9
谢谢你的帮助,但我仍然不明白为什么需要使用 __DIR__。PHP文档似乎说PHP会默认搜索当前脚本所在的目录。有人能解释一下吗? - David
1
@David 我认为当你同时从两个地方导入文件时,这是必需的。例如,你有一个带有 require "../a.php" 的文件。如果这个文件从另一个文件(x)中导入,在 dir1/dir2/x.php 中包含的文件将是 dir1/a.php,但如果 x 在 dir1/dir2/dir3/x.php 中,则包含的文件将是 dir1/dir2/a.php,等等。或者我错了吗? - José Ramón
1
现在针对这种常见错误,有一个故障排除清单,网址是:https://dev59.com/LVoV5IYBdhLWcg3wL8Ww#36577021 - Vic Seedoubleyew
显示剩余2条评论

20

对于 PHP 版本 5.2.17,__DIR__ 不会起作用,它只能在 PHP 5.3 中使用。

但是对于旧版本的 PHP,dirname(__FILE__) 可以完美地运行。

例如这样写:

require_once dirname(__FILE__) . '/db_config.php';

1
在我的情况下,即使使用__DIR__getcwd(),它仍然选择错误的路径,我通过在每个需要的文件中定义一个常量来解决这个问题,该常量包含项目的绝对基本路径。
if(!defined('THISBASEPATH')){ define('THISBASEPATH', '/mypath/'); }
require_once THISBASEPATH.'cache/crud.php';
/*every other require_once you need*/

我有安装了PHP 5.4.10的MAMP,我的文件夹层次结构很基础:
q.php 
w.php 
e.php 
r.php 
cache/a.php 
cache/b.php 
setting/a.php 
setting/b.php

....


0

我刚遇到了这个问题,之前一切都运行良好,直到我在一个 include 中使用了另一个 include。

require_once '../script/pdocrud.php';  //This worked fine up until I had an includes within another includes, then I got this error:
Fatal error: require_once() [function.require]: Failed opening required '../script/pdocrud.php' (include_path='.:/opt/php52/lib/php')

解决方案1:(不希望将我的公共HTML文件夹名称硬编码,但它可以工作):

require_once $_SERVER["DOCUMENT_ROOT"] . '/orders.simplystyles.com/script/pdocrud.php';

解决方案2。(上面关于DIR仅适用于php 5.3以上版本的不良评论,但它确实有效):

require_once __DIR__. '/../script/pdocrud.php';

解决方案3。(我看不到任何缺点,它在我的php 5.3中完美运行):

require_once dirname(__FILE__). '/../script/pdocrud.php';

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