266

I have searched high and low and get a lot of different solutions and variables containing info to get the absolute path. But they seem to work under some conditions and not under others. Is there one silver bullet way to get the absolute path of the executed script in PHP? For me, the script will run from the command line, but, a solution should function just as well if run within Apache etc.

Clarification: The initially executed script, not necessarily the file where the solution is coded.

Paolo
  • 15,233
  • 27
  • 70
  • 91
inquam
  • 12,664
  • 15
  • 61
  • 101
  • true indeed mathheadinclouds. I accepted it a long time ago when I had only one script and it worked for me. I removed the accepted answer to make it clear it does not solve the initial problem. Storing the FILE constant when the execution starts in a script is one way to go, but far from ideal. – inquam Nov 13 '14 at 12:45
  • **requested** script is what you wanted, current script = with this solution code – Bitterblue Nov 08 '19 at 07:50

14 Answers14

281

__FILE__ constant will give you absolute path to current file.

Update:

The question was changed to ask how to retrieve the initially executed script instead of the currently running script. The only (??) reliable way to do that is to use the debug_backtrace function.

$stack = debug_backtrace();
$firstFrame = $stack[count($stack) - 1];
$initialFile = $firstFrame['file'];
kbulgrien
  • 4,384
  • 2
  • 26
  • 43
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • If I'm using a front controller pattern. Would `__FILE__` return the index.php's location or the included file's location? How would I get the index.php's location? – CMCDragonkai Nov 15 '13 at 23:55
  • 1
    Well `__FILE__` does point to the current script's path. But I haven't found anything to shows the current index.php's path. – CMCDragonkai Nov 16 '13 at 00:36
  • 1
    @CMCDragonkai: ask a separate question then – zerkms Nov 16 '13 at 04:46
  • 2
    CAUTION: if the script is in an apache2 virtual directory, the information returned does NOT provide the real path location on the physical server. I wanted this for debug purposes, and even the $_SERVER variables do not provide this. For example, if index.php exists in /var/www/vpath1/html and /var/www/html/ and /var/www/vpath2/html, and each of these is virtually mapped to /var/www/html, then /var/www/html is what you will see, no matter which virtual server is used. – Mark Richards Jul 22 '14 at 14:50
  • @Mark Richards: what `__FILE__` returns is a **REAL** filesystem path. It doesn't care of any virtual servers or whatever else your webserver defines, but just a filesystem path. – zerkms Jul 22 '14 at 21:36
  • `__DIR__` is'nt a good choice? You get the absolute path for the current php file. – Redips77 Jul 31 '15 at 08:08
  • @Redips77 `__DIR__` does not return the absolute path to the current file, it returns the absolute path to the directory that hosts the current file. – zerkms Aug 02 '15 at 06:45
  • Note that my initial question was to get the initial executed script file (without manually saving it once executed). `__FILE__` will get you the current file you are in, not the file of the script/url that might have included the current file returned by `__FILE__` – inquam Aug 09 '15 at 19:19
  • @inquam actually I've put my question **BEFORE** you have put your note (9:05 vs 9:08). So your **initial question** that I actually answered did not contain it. I'm sorry I cannot read minds and answer questions to be asked 3 minutes after I answered them. – zerkms Aug 09 '15 at 21:14
  • @zerkms: My deepest appologies :)... I still get random *plings* in my phone related to this question to this date and still none have been able to answer it so happened to write something today. After some research into the code (valid at the time) I actually don't believe it is/was possible. Some combination using the _DOCUMENT_ROOT_ and _SCRIPT_NAME_ variables in the _$SERVER_ array would come close (and with some more info probably solve it). But I seem to remember some of the data in $SERVER being able to be spoofed or not presented in some configurations so I didn't want to rely on that. – inquam Aug 09 '15 at 21:19
  • @inquam the only **reliable** way to get the script that initiated runtime in php is using `debug_backtrace`. All other answers, including mine, do not answer the current question. – zerkms Aug 09 '15 at 21:30
  • @zerkms: Do _debug_backtrace_ still incure a massive performance hit? I know it did in old versions of PHP. – inquam Aug 09 '15 at 21:31
  • @inquam well, I'm not sure about its "massiveness", but if you need a *reliable* solution I don't see any other possibilities. Everything else may return just incorrect results. – zerkms Aug 09 '15 at 21:32
  • Throwing an exception instead of calling debug_backtrace() will basically give you the same backtrace information a lot quicker. – Christoffer Bubach Aug 20 '18 at 02:25
  • 1
    @ChristofferBubach you don't even need to throw it: an exception object collects the stack trace during construction. – zerkms Aug 20 '18 at 02:33
  • Yes, sorry - that's what I was meaning to write. – Christoffer Bubach Sep 01 '18 at 21:39
251
echo realpath(dirname(__FILE__));

If you place this in an included file, it prints the path to this include. To get the path of the parent script, replace __FILE__ with $_SERVER['PHP_SELF']. But be aware that PHP_SELF is a security risk!

rik
  • 8,592
  • 1
  • 26
  • 21
  • 1
    This was exactly what I wanted – inquam Jan 10 '11 at 09:08
  • 13
    what's the use of realpath here? – Your Common Sense Jan 10 '11 at 09:09
  • 2
    What is the security risk of using `$_SERVER['PHP_SELF']` ? Because people echo it and it contains the URL which may be malicious? – alex Jan 10 '11 at 09:20
  • 11
    @Col. Shrapnel: "Since PHP 4.0.2, `__FILE__` always contains an absolute path with symlinks resolved whereas in older versions it contained relative path under some circumstances." plus "dirname() operates naively on the input string, and is not aware of the actual filesystem, or path components such as '..'. – rik Jan 10 '11 at 09:49
  • 2
    @rik: also, what security issue can cause `PHP_SELF` ?? – zerkms Jan 10 '11 at 09:53
  • 1
    @zerkms it can't be. 5.0.2 probably. 4.0.2 is < 4.1 and 4.1 itself is as ancient, as dino's petrified shit – Your Common Sense Jan 10 '11 at 09:57
  • 1
    @Col. Shrapnel: yep, it is 1999. I thought I can rely on dates at museum.php.net. – zerkms Jan 10 '11 at 09:58
  • Why do you need realpath? Is dirname not enough on its own? – Benubird Jul 21 '15 at 07:25
  • 1
    as of PHP>=5.3.0, `echo __DIR__` is the equivalent – Meisner Apr 20 '17 at 11:04
  • As far as I can see PHP_SELF is only a security risk when using it on forms. `__DIR__` is *not* the same as PHP_SELF, by the way. – Bram Vanroy May 13 '17 at 07:34
  • Both options in the answer don't not return (i) absolute path (ii) the "initially run" script – Salman A Jun 09 '22 at 16:31
  • Still not usefull in this case. 1 request to /phpfiledir/other/random/path. So PHP_SELF would output the whole path. while index.php is hosted in /phpfiledir. and the other path is handled by the script. – JulenAtWork Mar 02 '23 at 14:26
45

The correct solution is to use the get_included_files function:

list($scriptPath) = get_included_files();

This will give you the absolute path of the initial script even if:

  • This function is placed inside an included file
  • The current working directory is different from initial script's directory
  • The script is executed with the CLI, as a relative path

Here are two test scripts; the main script and an included file:

# C:\Users\Redacted\Desktop\main.php
include __DIR__ . DIRECTORY_SEPARATOR . 'include.php';
echoScriptPath();

# C:\Users\Redacted\Desktop\include.php
function echoScriptPath() {
    list($scriptPath) = get_included_files();
    echo 'The script being executed is ' . $scriptPath;
}

And the result; notice the current directory:

C:\>php C:\Users\Redacted\Desktop\main.php
The script being executed is C:\Users\Redacted\Desktop\main.php
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • 1
    This solution works but it's worth mentioning that, reading the [documentation](https://www.php.net/manual/en/function.get-included-files.php), there is no mention that the initially run script's path is the **first** item of the array returned by `get_included_files()`. I [suggest](https://stackoverflow.com/a/48158945/1579327) to store `__FILE__` into a constant at the beginning of the script meant to be initially run. – Paolo Nov 16 '19 at 14:04
42
__DIR__

From the manual:

The directory of the file. If used inside an include, the directory of the included file is returned. This is equivalent to dirname(__FILE__). This directory name does not have a trailing slash unless it is the root directory.
__FILE__ always contains an absolute path with symlinks resolved whereas in older versions (than 4.0.2) it contained relative path under some circumstances.

Note: __DIR__ was added in PHP 5.3.0.

MAChitgarha
  • 3,728
  • 2
  • 33
  • 40
Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
23

If you want to get current working directory use getcwd()

http://php.net/manual/en/function.getcwd.php

__FILE__ will return path with filename for example on XAMPP C:\xampp\htdocs\index.php instead of C:\xampp\htdocs\

pkarecki
  • 241
  • 3
  • 5
8
dirname(__FILE__) 

will give the absolute route of the current file from which you are demanding the route, the route of your server directory.

example files :

www/http/html/index.php ; if you place this code inside your index.php it will return:

<?php echo dirname(__FILE__); // this will return: www/http/html/

www/http/html/class/myclass.php ; if you place this code inside your myclass.php it will return:

<?php echo dirname(__FILE__); // this will return: www/http/html/class/

Sultanos
  • 463
  • 7
  • 12
6

Just use below :

echo __DIR__;
Matricore
  • 575
  • 7
  • 12
  • 1
    Sry, the idea is to get the first fired script... Not the one you happen to be in now. So an inclusion tree of `a.php->b.php->c.php` should be the path of **a.php** if checked in **c.php**. The only way that seems to be reliable is to use the *debug_backtrace()* function. – inquam Nov 05 '15 at 14:30
5
`realpath(dirname(__FILE__))` 

it gives you current script(the script inside which you placed this code) directory without trailing slash. this is important if you want to include other files with the result

MinhajulAnwar
  • 408
  • 6
  • 10
  • Yea, but the idea is to be able to get the absolute path to the "firing script" A.php even inside B.php if that is included by A.php. It CAN or course be done by storing the initial script for later access, but the question was if it's possible to get it without doing that. – inquam Feb 25 '15 at 14:47
5

A simple way to have the absolute path of the initially executed script, in that script and any other script included with include, require, require_once is by using a constant and storing there the current script path at beginning of the main script:

define( 'SCRIPT_ROOT', __FILE__ );

The solution above is suitable when there is a single "main" script that includes every other needed script, as in most may web applications, tools and shell scripts.

If that's not the case and there may be several "intital scripts" then to avoid redefinitions and to have the correct path stored inside the constant each script may begin with:

if( ! defined( 'SCRIPT_ROOT' ) ) {
    define( 'SCRIPT_ROOT`, __FILE__ );
}

A note about the (currently) accepted answer:

the answer states that the initially executed script path is the first element of the array returned by get_included_files().

This is a clever and simple solution and -at the time of writing- (we're almost at PHP 7.4.0) it does work.

However by looking at the documentation there is no mention that the initially executed script is the first item of the array returned by get_included_files().

We only read

The script originally called is considered an "included file," so it will be listed together with the files referenced by include and family.

At the time of writing the "script originally called" is the first one in the array but -technically- there is no guarantee that this won't change in the future.


A note about realpath(), __FILE__, and __DIR__:

Others have suggested in their answers the use of __FILE__, __DIR__, dirname(__FILE__), realpath(__DIR__)...

dirname(__FILE__) is equal to __DIR__ (introduced in PHP 5.3.0), so just use __DIR__.

Both __FILE__ and __DIR__ are always absolute paths so realpath() is unnecessary.

Paolo
  • 15,233
  • 27
  • 70
  • 91
4

If you're looking for the absolute path relative to the server root, I've found that this works well:

$_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['SCRIPT_NAME'])
SiteKickr
  • 249
  • 3
  • 7
  • When I was checking this solution against different servers it always gave me path with the linux like dir separators regardless of host's OS (Windows and Linux). To me that is an advantage. – Bronek Dec 29 '16 at 21:07
4

Here's a useful PHP function I wrote for this precisely. As the original question clarifies, it returns the path from which the initial script was executed - not the file we are currently in.

/**
 * Get the file path/dir from which a script/function was initially executed
 * 
 * @param bool $include_filename include/exclude filename in the return string
 * @return string
 */ 
function get_function_origin_path($include_filename = true) {
    $bt = debug_backtrace();
    array_shift($bt);
    if ( array_key_exists(0, $bt) && array_key_exists('file', $bt[0]) ) {
        $file_path = $bt[0]['file'];
        if ( $include_filename === false ) {
            $file_path = str_replace(basename($file_path), '', $file_path);
        }
    } else {
        $file_path = null;
    }
    return $file_path;
}
blizzrdof77
  • 363
  • 4
  • 14
2
realpath($_SERVER['SCRIPT_FILENAME'])

For script run under web server $_SERVER['SCRIPT_FILENAME'] will contain the full path to the initially called script, so probably your index.php. realpath() is not required in this case.

For the script run from console $_SERVER['SCRIPT_FILENAME'] will contain relative path to your initially called script from your current working dir. So unless you changed working directory inside your script it will resolve to the absolute path.

Victor
  • 750
  • 9
  • 9
1

try this on your script

echo getcwd() . "\n";
Shuhad zaman
  • 3,156
  • 32
  • 32
1

This is what I use and it works in Linux environments. I don't think this would work on a Windows machine...

//define canonicalized absolute pathname for the script
if(substr($_SERVER['SCRIPT_NAME'],0,1) == DIRECTORY_SEPARATOR) {
    //does the script name start with the directory separator?
    //if so, the path is defined from root; may have symbolic references so still use realpath()
    $script = realpath($_SERVER['SCRIPT_NAME']);
} else {
    //otherwise prefix script name with the current working directory
    //and use realpath() to resolve symbolic references
    $script = realpath(getcwd() . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_NAME']);
}
andrewniesen
  • 376
  • 2
  • 12