I'm having trouble understanding the ruleset regarding PHP relative include paths. If I run file A.PHP- and file A.PHP includes file B.PHP which includes file C.PHP, should the relative path to C.PHP be in relation to the location of B.PHP, or to the location of A.PHP? That is, does it matter which file the include is called from, or only what the current working directory is- and what determines the current working directory?
It's relative to the main script, in this case A.php. Remember that
include() just inserts code into the currently running script.
That is, does it matter which file the include is called from
If you want to make it matter, and do an include relative to B.php, use the
__FILE__ constant (or
__DIR__ since PHP 5.2 IIRC) which will always point to the literal current file that the line of code is located in.
@Pekka got me there, but just want to share what I learned:
getcwd() returns the directory where the file you started executing resides.
dirname(__FILE__) returns the directory of the file containing the currently executing code.
Using these two functions, you can always build an include path relative to what you need.
e.g., if b.php and c.php share a directory, b.php can include c.php like:
no matter where b.php was called from.
In fact, this is the preferred way of establishing relative paths, as the extra code frees PHP from having to iterate through the include_path in the attempt to locate the target file.
The accepted answer of Pekka is incomplete and, in a general context, misleading. If the file is provided as a relative path, the called language construct
include will search for it in the following way.
First, it will go through the paths of the environment variable
include_path, which can be set with
ini_set. If this fails, it will search in the calling script's own directory
__DIR__ with php >= 5.3.) If this also fails, only then it will search in the working directory ! It just turns out that, by default, the environment variable
include_path begins with
., which is the current working directory. That is the only reason why it searches first in the current working directory. See http://php.net/manual/en/function.include.php.
Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing.
So, the correct answer to the first part of the question is that it does matter where is located the included calling script. The answer to the last part of the question is that the initial working directory, in a web server context, is the directory of the called script, the script that includes all the others while being handled by PHP. In a command line context, the initial working directory is whatever it is when php is invoked at the prompt, not necessarily the directory where the called script is located. The current working directory, however, can be changed at run time with the PHP function
chdir. See http://php.net/manual/en/function.chdir.php.
This paragraph is added to comment on other answers. Some have mentioned that relying on
include_path is less robust and thus it is preferable to use full paths such as
__DIR__ . /path. Some went as far as saying that relying on the working directory
. itself is not safe, because it can be changed. However, some times, you need to rely on environment values. For example, you might want set
include_path empty, so that the directory of the calling script is the first place that it will search, even before the current working directory. The code might be already written and updated regularly from external sources and you do not want to reinsert the prefix
__DIR__ each time the code is updated.
If include path doesn't start with
include 'C.php'; // precedence: include_path (which include '.' at first), // then path of current `.php` file (i.e. `B.php`), then `.`.
If include path starts with
include './C.php'; // relative to '.' include '../C.php'; // also relative to '.'
.. above is relative to
getcwd(), which defaults to the path of the entry
.php file (i.e.
Tested on PHP 5.4.3 (Build Date : May 8 2012 00:47:34).
(Also note that
chdir() can change the output of
Short answer: it's relative to the including script.
TFM explains it correctly:
If the file isn't found in the include_path, include will check in the calling script's directory and the current working directory
So, if /app/main.php says
include("./inc.php") that will find /app/inc.php.
The ./ is not strictly necessary but removes any dependency on include_path.
I would not rely on finding include files in the current working directory in case someone changes it with
dir -> a.php -> c.php - dir2 -> b.php
b you need to
c you need to