Are PHP include paths relative to the file or the calling code?
Solution 1
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
No.
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.
include(dirname(__FILE__)."/C.PHP");
Solution 2
@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:
include(dirname(__FILE__).'/c.php');
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.
Sources:
Difference Between getcwd() and dirname(__FILE__) ? Which should I use?
Why you should use dirname(__FILE__)
Solution 3
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 dirname(__FILE__)
(__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 ./path
or __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.
Solution 4
-
If include path doesn't start with
./
or../
, e.g.: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
./
or../
, e.g.:include './C.php'; // relative to '.' include '../C.php'; // also relative to '.'
The .
or ..
above is relative to getcwd()
, which defaults to the path of the entry .php
file (i.e. A.php
).
Tested on PHP 5.4.3 (Build Date : May 8 2012 00:47:34).
(Also note that chdir()
can change the output of getcwd()
.)
Solution 5
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 chdir()
.
Related videos on Youtube
Yarin
Products PDF Buddy - Popular online PDF editor Gems Snappconfig - Smarter Rails app configuration
Updated on July 08, 2022Comments
-
Yarin almost 2 years
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?
-
Admin over 6 yearsMore accurate than accepted answer in my opinion : stackoverflow.com/a/23902890/1636522.
-
-
Yarin over 12 years@Pekka- awesome- just what I was looking for. For further info, see stackoverflow.com/questions/2184810/…
-
Yarin over 12 years@Olli- you're missing the point of the question- I was asking about how relative paths are determined when includes are chained.
-
Johnny Wong almost 10 yearsTo conclude, A.php's path is first searched for C.php, then B.php's path is searched if no prefix './' or '../' in the include. (Assume default PHP's setting)
-
Nick Bedford over 9 yearsYou can also use
__DIR__
for that exact purpose. -
Pacerier over 9 yearsSo if you start the string with
./
, does it check the calling script's directory first or the current working directory first? -
Johnny Wong about 9 yearsThis answer is somewhat overkill: NO NEED
include(dirname(__FILE__)."/C.PHP");
, becauseinclude("C.PHP");
is enough (Yes! C.PHP can be in same directory as B.PHP) It may fail only when there are two C.PHP files in your project. -
Johnny Wong about 9 yearsTo make it more clear: It is relative to both B.php and A.php if without "./" or "../" prefix in the include path. See my answer below.
-
HartleySan almost 8 yearsThanks for cluing me in to using
chdir(__DIR__)
to fix the problem. -
Johnny Wong over 7 years@Denis Howe No, you are already depending on the current working directory if your include path start with
./
. i.e. chdir("/app/other") will makeinclude("./inc.php")
fail. Thus, useinclude("inc.php")
to be safe in this case. -
Johnny Wong over 7 years@Pacerier if the string start the with ./ or ../, it only check current working directory. (include_path and directory of calling script (B.php) are both ignored). See my answer for more detail.
-
Miguel Vieira almost 7 yearsI'd like to add something, I had a file called csb.php, included a functions file from a folder, and the functions file included a file named t.php from the same folder as the functions file, When I tried including a file named csb.php from the folder t.php was, it started including the same csb.php that called the functions file, but when I changed the second csb.php to csbe.php it started working right away. So, it looks like it priorizes the first folder, then the second include folder!
-
herzbube about 6 years[...]
getcwd()
, which defaults to the path of the entry .php file [...] - not necessarily true. If I run PHP on the command line thengetcwd()
refers to the current working directory of the shell, regardless of which.php
file I invoke. I can imagine, though, that if PHP is run in a web server environment that the environment initializes the current working directory to the entry.php
file. Tested on macOS with PHP 7.2.2 installed via Homebrew. -
Sz. about 6 years"if this fails, it will search in the calling script's own directory
dirname(__FILE__)
(__DIR__)
with php >= 5.3.)" Are you sure? Where is it documented? I hope you are wrong, and PHP does not use__FILE__
and__DIR__
for this purpose, as that would promptly break including "sibling" scripts from symlinked ones! :-o (Which, fortunately, appears to work fine here, on my 7.1 setup.) -
Kevin Y almost 2 years@JohnnyWong It can fail in many ways. PHP can have its include_path misconfigured if
.
doesn't appear in it and thus it won't look in current working directory. Also the working directory can change, either by the entry point or by changing it with chdir (as shown in your post). When going through relative includes, it needs to go through the full list of include_paths and it could potentially find the "wrong" file depending on configuration. It's a lot less error prone to use absolute paths: e.g.__DIR__
,dirname(__FILE__)
etc. But feel free to use relative paths if you know the risks. -
G M almost 2 yearsNote that the
dirname
function has an optional second parameter (type integer) that enables you to traverse 'n' number of parent directories relative to the current script. You can find more details here: php.net/manual/en/function.dirname.php