77

I have file /root/update/test.php. There's also a file, /root/connect.php; This file has a line

include "../config.php";

In /root/update/test.php. There's the code

set_include_path(".:/root");
include "connect.php";

When I run /root/update/test.php, it finds connect.php, but fails to find config.php, giving me

PHP Warning:  include(../config.php): failed to open stream: No such file or directory in /root/connect.php on line 2
PHP Warning:  include(): Failed opening '../config.php' for inclusion (include_path='.:/root')

This is confusing to me because the warnings make it seem like I'm doing everything correctly - the include path is /root, and it's looking for file ../config.php (/config.php), which exists. Can someone clear this up for me? Note that using absolute paths is not an option for me, due to deploying to a production server that I have no access to.

Ubuntu/Apache

George B
  • 2,592
  • 3
  • 22
  • 27

2 Answers2

159

You could always include it using __DIR__:

include(dirname(__DIR__).'/config.php');

__DIR__ is a 'magical constant' and returns the directory of the current file without the trailing slash. It's actually an absolute path, you just have to concatenate the file name to __DIR__. In this case, as we need to ascend a directory we use PHP's dirname which ascends the file tree, and from here we can access config.php.

You could set the root path in this method too:

define('ROOT_PATH', dirname(__DIR__) . '/');

in test.php would set your root to be at the /root/ level.

include(ROOT_PATH.'config.php');

Should then work to include the config file from where you want.

Julix
  • 598
  • 1
  • 9
  • 20
meiamsome
  • 2,876
  • 1
  • 17
  • 19
  • 3
    If you plan to use these constants with relative paths (i.e. `../`), I would encourage you to clean it up with `realpath()` before the `define()`. – Jason McCreary Jul 01 '13 at 17:15
  • 1
    Instead of using `ROOT_PATH.'../'`, I would use `dirname(ROOT_PATH)`. The latter would give you a "more absolute" path. – Kayla Mar 19 '14 at 00:29
  • I have started a troubleshooting checklist for this frequent error here : stackoverflow.com/a/36577021/2873507 – Vic Seedoubleyew Apr 12 '16 at 15:20
  • You should consider that in windows dirname(__DIR__) get directory but with windows slash, so this method will just work with linux systems –  Nov 18 '18 at 18:50
  • so with this (your answer), we use absolute path instead of relative, right? – Adi Prasetyo Feb 05 '19 at 11:29
  • I think include(\_\_DIR\_\_."/../config.php"); looks much better. – zomega Dec 02 '22 at 11:07
1

While I appreciate you believe absolute paths is not an option, it is a better option than relative paths and updating the PHP include path.

Use absolute paths with an constant you can set based on environment.

if (is_production()) {
    define('ROOT_PATH', '/some/production/path');
}
else {
    define('ROOT_PATH', '/root');
}

include ROOT_PATH . '/connect.php';

As commented, ROOT_PATH could also be derived from the current path, $_SERVER['DOCUMENT_ROOT'], etc.

Jason McCreary
  • 71,546
  • 23
  • 135
  • 174