How do i set the path of a file in php?

In HTML, I can find a file starting from the web server's root folder by beginning the filepath with "/". Like:

/images/some_image.jpg

I can put that path in any file in any subdirectory, and it will point to the right image.

With PHP, I tried something similar:

include("/includes/header.php");

...but that doesn't work.

I think that that this page is saying that I can set include_path once and after that, it will be assumed. But I don't quite get the syntax. Both examples start with a period, and it says:

Using a . in the include path allows for relative includes as it means the current directory.

Relative includes are exactly what I don't want.

How do I make sure that all my includes point to the root/includes folder? (Bonus: what if I want to place that folder outside the public directory?)

Clarification

My development files are currently being served by XAMPP/Apache. Does that affect the absolute path? (I'm not sure yet what the production server will be.)

Update

I don't know what my problem was here. The include_path thing I referenced above was exactly what I was looking for, and the syntax isn't really confusing. I just tried it and it works great.

One thing that occurs to me is that some people may have thought that "/some/path" was an "absolute path" because they assumed the OS was Linux. This server is Windows, so an absolute path would have to start with the drive name.

Anyway, problem solved! :)

(PHP 4, PHP 5, PHP 7, PHP 8)

realpathReturns canonicalized absolute pathname

Description

realpath(string $path): string|false

Parameters

path

The path being checked.

Note:

Whilst a path must be supplied, the value can be an empty string. In this case, the value is interpreted as the current directory.

Return Values

Returns the canonicalized absolute pathname on success. The resulting path will have no symbolic link, /./ or /../ components. Trailing delimiters, such as \ and /, are also removed.

realpath() returns false on failure, e.g. if the file does not exist.

Note:

The running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return false.

Note:

For case-insensitive filesystems realpath() may or may not normalize the character case.

Note:

The function realpath() will not work for a file which is inside a Phar as such path would be a virtual path, not a real one.

Note:

On Windows, junctions and symbolic links to directories are only expanded by one level.

Note: Because PHP's integer type is signed and many platforms use 32bit integers, some filesystem functions may return unexpected results for files which are larger than 2GB.

Examples

Example #1 realpath() example

chdir('/var/www/');
echo 
realpath('./../../etc/passwd') . PHP_EOL;

echo

realpath('/tmp/') . PHP_EOL;
?>

The above example will output:

Example #2 realpath() on Windows

On windows realpath() will change unix style paths to windows style.

echo realpath('/windows/system32'), PHP_EOL;

echo

realpath('C:\Program Files\\'), PHP_EOL;
?>

The above example will output:

C:\WINDOWS\System32
C:\Program Files

See Also

  • basename() - Returns trailing name component of path
  • dirname() - Returns a parent directory's path
  • pathinfo() - Returns information about a file path

Sven Arduwie

14 years ago

Because realpath() does not work on files that do not
exist, I wrote a function that does.
It replaces (consecutive) occurences of / and \\ with
whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine.
Paths returned by get_absolute_path() contain no
(back)slash at position 0 (beginning of the string) or
position -1 (ending)
    function get_absolute_path($path) {
       
$path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path);
       
$parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
       
$absolutes = array();
        foreach (
$parts as $part) {
            if (
'.' == $part) continue;
            if (
'..' == $part) {
               
array_pop($absolutes);
            } else {
               
$absolutes[] = $part;
            }
        }
        return
implode(DIRECTORY_SEPARATOR, $absolutes);
    }
?>

A test:
    var_dump(get_absolute_path('this/is/../a/./test/.///is'));
?>
Returns: string(14) "this/a/test/is"

As you can so, it also produces Yoda-speak. :)

moreau dot marc dot web at gmail dot com

2 years ago

namespace MockingMagician\Organic\Helper;

class

Path
{
   
/**
     * There is a method that deal with Sven Arduwie proposal https://www.php.net/manual/en/function.realpath.php#84012
     * And runeimp at gmail dot com proposal https://www.php.net/manual/en/function.realpath.php#112367
     * @param string $path
     * @return string
     */
   
public static function getAbsolute(string $path): string
   
{
       
// Cleaning path regarding OS
       
$path = mb_ereg_replace('\\\\|/', DIRECTORY_SEPARATOR, $path, 'msr');
       
// Check if path start with a separator (UNIX)
       
$startWithSeparator = $path[0] === DIRECTORY_SEPARATOR;
       
// Check if start with drive letter
       
preg_match('/^[a-z]:/', $path, $matches);
       
$startWithLetterDir = isset($matches[0]) ? $matches[0] : false;
       
// Get and filter empty sub paths
       
$subPaths = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'mb_strlen');$absolutes = [];
        foreach (
$subPaths as $subPath) {
            if (
'.' === $subPath) {
                continue;
            }
           
// if $startWithSeparator is false
            // and $startWithLetterDir
            // and (absolutes is empty or all previous values are ..)
            // save absolute cause that's a relative and we can't deal with that and just forget that we want go up
           
if ('..' === $subPath
               
&& !$startWithSeparator
               
&& !$startWithLetterDir
               
&& empty(array_filter($absolutes, function ($value) { return !('..' === $value); }))
            ) {
               
$absolutes[] = $subPath;
                continue;
            }
            if (
'..' === $subPath) {
               
array_pop($absolutes);
                continue;
            }
           
$absolutes[] = $subPath;
        }

        return
            ((

$startWithSeparator ? DIRECTORY_SEPARATOR : $startWithLetterDir) ?
               
$startWithLetterDir.DIRECTORY_SEPARATOR : ''
           
).implode(DIRECTORY_SEPARATOR, $absolutes);
    }
/**
     * Examples
     *
     * echo Path::getAbsolute('/one/two/../two/./three/../../two');            =>    /one/two
     * echo Path::getAbsolute('../one/two/../two/./three/../../two');          =>    ../one/two
     * echo Path::getAbsolute('../.././../one/two/../two/./three/../../two');  =>    ../../../one/two
     * echo Path::getAbsolute('../././../one/two/../two/./three/../../two');   =>    ../../one/two
     * echo Path::getAbsolute('/../one/two/../two/./three/../../two');         =>    /one/two
     * echo Path::getAbsolute('/../../one/two/../two/./three/../../two');      =>    /one/two
     * echo Path::getAbsolute('c:\.\..\one\two\..\two\.\three\..\..\two');     =>    c:/one/two
     *
     */
}

runeimp at gmail dot com

9 years ago

Needed a method to normalize a virtual path that could handle .. references that go beyond the initial folder reference. So I created the following.
function normalizePath($path)
{
   
$parts = array();// Array to build a new path from the good parts
   
$path = str_replace('\\', '/', $path);// Replace backslashes with forwardslashes
   
$path = preg_replace('/\/+/', '/', $path);// Combine multiple slashes into a single slash
   
$segments = explode('/', $path);// Collect path segments
   
$test = '';// Initialize testing variable
   
foreach($segments as $segment)
    {
        if(
$segment != '.')
        {
           
$test = array_pop($parts);
            if(
is_null($test))
               
$parts[] = $segment;
            else if(
$segment == '..')
            {
                if(
$test == '..')
                   
$parts[] = $test;

                if(

$test == '..' || $test == '')
                   
$parts[] = $segment;
            }
            else
            {
               
$parts[] = $test;
               
$parts[] = $segment;
            }
        }
    }
    return
implode('/', $parts);
}
?>

Will convert /path/to/test/.././..//..///..///../one/two/../three/filename
to ../../one/three/filename

plamen at dragiyski dot org

3 years ago

realpath() is just a system/library call to actual realpath() function supported by OS. It does not work on a path as a string, but also resolves symlinks. The resulting path might significantly differs from the input even when absolute path is given. No function in this notes resolves that.

The suggestion on the realpath man page is to look for an existing parent directory. Here is an example:
    function resolvePath($path) {
        if(
DIRECTORY_SEPARATOR !== '/') {
           
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
        }
       
$search = explode('/', $path);
       
$search = array_filter($search, function($part) {
            return
$part !== '.';
        });
       
$append = array();
       
$match = false;
        while(
count($search) > 0) {
           
$match = realpath(implode('/', $search));
            if(
$match !== false) {
                break;
            }
           
array_unshift($append, array_pop($search));
        };
        if(
$match === false) {
           
$match = getcwd();
        }
        if(
count($append) > 0) {
           
$match .= DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $append);
        }
        return
$match;
    }
?>

The result will retrieve absolute path for non-existing relative path. Even if a path does not exists, there should be existing directory somewhere, for which the realpath could be obtained. If this is not within the relative path (i.e. even current working directory does not exists), getcwd() will retrieve absolute path, so some absolute path is returned (although in that case the PHP process could have huge problems).

Anonymous

10 years ago

Note: If you use this to check if a file exists, it's path will be cached, and returns true even if the file is removed (use file_exists instead).

David Beck

15 years ago

Here's a function to canonicalize a URL containing relative paths. Ran into the problem when pulling links from a remote page.

function canonicalize($address)
{
   
$address = explode('/', $address);
   
$keys = array_keys($address, '..');

    foreach(

$keys AS $keypos => $key)
    {
       
array_splice($address, $key - ($keypos * 2 + 1), 2);
    }
$address = implode('/', $address);
   
$address = str_replace('./', '', $address);
}
$url = 'http://www.example.com/something/../else';
echo
canonicalize($url); //http://www.example.com/else?>

pulstar at ig dot com dot br

17 years ago

Sometimes you may need to refer to the absolute path of a file in your website instead of a relative path, but the realpath() function returns the path relative to the server's filesystem, not a path relative to your website root directory.

For example, realpath() may return something like this:

/home/yoursite/public_html/dir1/file.ext

You can't use this in an HTML document, because the web server will not find the file. To do so, you can use:

function htmlpath($relative_path) {
   
$realpath=realpath($relative_path);
   
$htmlpath=str_replace($_SERVER['DOCUMENT_ROOT'],'',$realpath);
    return
$htmlpath;
}

echo

''; ?>

It will return something like:

Jrg Wagner

12 years ago

Please be aware that this function does NOT always strip a trailing slash!:

LINUX (tested with PHP 5.2.11):
---
realpath('.')
: string = "/myhttpdfolder"
realpath('./')
: string = "/myhttpdfolder"
realpath('fileadmin')
: string = "/myhttpdfolder/fileadmin"
realpath('fileadmin/')
: string = "/myhttpdfolder/fileadmin"

WINDOWS (tested with PHP 5.2.5):
---
realpath('.')
: string = "C:\\myhttpdfolder"
realpath('./')
: string = "C:\\myhttpdfolder\\"
realpath('fileadmin')
: string = "C:\\myhttpdfolder\\fileadmin"
realpath('fileadmin/')
: string = "C:\\myhttpdfolder\\fileadmin\\"

Vincent Par

7 years ago

Beware of relative symbolic links like this one (ext4 file system on Ubuntu) :

    vincent@vincent:~/Bureau/dirscan$ readlink sandbox/roulant/voiture/cabriolet/ln-loop-relative
    ../..

In this case, realpath may return false :

var_dump(realpath('sandbox/roulant/voiture/cabriolet/ln-loop-relative'));
// => string(44) "/home/vincent/Bureau/dirscan/sandbox/roulant"
var_dump(realpath('sandbox/roulant/voiture/cabriolet/ln-loop-relative/moto'));
// => bool(false)
?>

But you can fix it by clearing the realpath cache, this way :

var_dump(realpath('sandbox/roulant/voiture/cabriolet/ln-loop-relative'));
clearstatcache(true);
var_dump(realpath('sandbox/roulant/voiture/cabriolet/ln-loop-relative/moto'));
// => string(49) "/home/vincent/Bureau/dirscan/sandbox/roulant/moto"
?>

imagiro

11 years ago

Here is a small and handy method to calculate the relative path from $from to $to. Note: On Windows it does not work when $from and $to are on different drives.

function relativePath($from, $to, $ps = DIRECTORY_SEPARATOR)
{
 
$arFrom = explode($ps, rtrim($from, $ps));
 
$arTo = explode($ps, rtrim($to, $ps));
  while(
count($arFrom) && count($arTo) && ($arFrom[0] == $arTo[0]))
  {
   
array_shift($arFrom);
   
array_shift($arTo);
  }
  return
str_pad("", count($arFrom) * 3, '..'.$ps).implode($ps, $arTo);
}
?>

eion at robbmob dot com

6 years ago

Be aware that realpath() doesn't work with hidden Windows UNC paths, eg  \\servername\share$\folder\blah.txt but other PHP file-functions can access that file fine.

php at keith tyler dot com

10 years ago

Note that under Windows, a slash-rooted path will resolve on the local drive, and *not* necessarily C:\.

For example:

M:\>php -r "print realpath('/AUTOEXEC.BAT');"
[prints nothing, because there is no M:\AUTOEXEC.BAT]

But:

M:\>C:
C:\>php -r "print realpath('/AUTOEXEC.BAT');"
C:\AUTOEXEC.BAT

Same script, different response depending on current drive.

I'm inclined to argue that this function *should* use the value of %SystemDrive% as the "slash root" base.

Lars Scheithauer

17 years ago

This function is also nice to test for security-breaches. You can forbid the script to access files below a certain directory to prevent "../../../etc/shadow" and similar attacks:

// declare the basic directory for security reasons
// Please do NOT attach a "/"-suffix !
$basedir = '/var/www/cgi-bin/scriptfolder';// compare the entered path with the basedir
$path_parts = pathinfo($_REQUEST['file_to_get']);
if (
realpath($path_parts['dirname']) != $basedir) {
   
/* appropriate action against crack-attempt*/
   
die ('coding good - h4x1ng bad!');
}
?>

The url "script.php?file_to_get=../../../etc/shadow" will now result in an error.

Leonard Challis

9 years ago

When using realpath (and similar functions) remember that PHP will take in to account open_basedir restrictions. So, if you do something like:

// test.php in httpdocs folder
$path = realpath(dirname(__FILE__) . '/../application');
?>

where your open_basedir setting is set to the httpdocs folder and tmp, this will return false. You must set it to the level above (or off) for this to work.

Enzo dot Barbaguelatta at alma dot cl

6 months ago

Be noticed that, one of the reasons of realtpath retuning false can be if the path does not exist, or it has permission issues, or even if security modules of your operating system (let's say, SELinux for example) avoids you checking the path.

If you're like me and you had a not very good time checking why realpath retuns false, please check these points first.

How do I change the location of a file in PHP?

To get the exact path of file, then, you can use realpath(). In between the round brackets of the function, type the name of the file. $dir = dirname("folder/myphp/fileDir.

How do you set the path to a file?

Here's the different syntax you need to know for dealing with paths:.
start with nothing or ./ — single dot + slash. Start in the same location as this file and work from there. ... .
../ — double dot + slash. ... .
/ — slash at the beginning. ... .
// — double slash at the beginning..

How do I find the path of a file in PHP?

The is_dir() function in PHP used to check whether the specified file is a directory or not. The name of the file is sent as a parameter to the is_dir() function and it returns True if the file is a directory else it returns False.

What is __ DIR __ in PHP?

The __DIR__ can be used to obtain the current code working directory. It has been introduced in PHP beginning from version 5.3. It is similar to using dirname(__FILE__). Usually, it is used to include other files that is present in an included file.