realpath

(PHP 4, PHP 5)

realpathReturns canonicalized absolute pathname

Description

string realpath ( string $path )

realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input path and returns the canonicalized absolute pathname.

Parameters

path

The path being checked.

Note:

Whilst a path must be supplied, the value can be blank or NULL In these cases, 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.

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: 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.

Changelog

Version Description
5.3.0 Prior to this release, if only the last path component did not exist, realpath() would not fail on *BSD systems. realpath() now fails in this case.
5.0.0 Prior to this release, a blank or NULL path would cause realpath() to return the directory name of the script.

Examples

Example #1 realpath() example

<?php
chdir
('/var/www/');
echo 
realpath('./../../etc/passwd');
?>

The above example will output:

/etc/passwd

Example #2 realpath() on Windows

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

<?php
echo realpath('/windows/system32');
?>

The above example will output:

C:\WINDOWS\System32

See Also

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

Коментарии

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:

<?php

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

echo 
'<img src="',htmlpath('../../relative/path/to/file.ext'),'" border=1>'

?>

It will return something like:

<img src="/dir1/relative/path/to/file.ext" border=1>
2004-12-20 15:43:27
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
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:

<?php

// 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.
2005-06-08 13:44:51
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
Here's a function to canonicalize a URL containing relative paths. Ran into the problem when pulling links from a remote page.

<?php

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

    foreach(
$keys AS $keypos => $key)
    {
       
array_splice($address$key - ($keypos 1), 2);
    }

   
$address implode('/'$address);
   
$address str_replace('./'''$address);
}

$url 'http://www.example.com/something/../else';
echo 
canonicalize($url); //http://www.example.com/else

?>
2006-11-22 21:38:23
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
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)
<?php
   
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:
<?php
    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. :)
2008-06-23 18:43:59
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
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\\"
2010-06-11 03:35:26
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
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.

<?php
function relativePath($from$to$ps DIRECTORY_SEPARATOR)
{
 
$arFrom explode($psrtrim($from$ps));
 
$arTo explode($psrtrim($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);
}
?>
2011-09-21 17:20:40
http://php5.kiev.ua/manual/ru/function.realpath.html
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.
2011-10-18 15:15:56
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
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).
2012-05-31 19:48:59
http://php5.kiev.ua/manual/ru/function.realpath.html
Needed a method to normalize a virtual path that could handle .. references that go beyond the initial folder reference. So I created the following.
<?php

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
2013-06-07 14:37:12
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
When using realpath (and similar functions) remember that PHP will take in to account open_basedir restrictions. So, if you do something like:

<?php
// 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.
2013-07-17 10:40:09
http://php5.kiev.ua/manual/ru/function.realpath.html
Автор:
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 :

<?php
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 :

<?php
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"
?>
2015-04-21 16:33:21
http://php5.kiev.ua/manual/ru/function.realpath.html
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.
2015-12-07 00:42:38
http://php5.kiev.ua/manual/ru/function.realpath.html
It should probably be expressly noted that tilde expansion is not performed by realpath.
2017-08-30 21:38:45
http://php5.kiev.ua/manual/ru/function.realpath.html
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:
<?php
   
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($appendarray_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).
2019-04-16 17:27:21
http://php5.kiev.ua/manual/ru/function.realpath.html
<?php

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
     *
     */
}
2019-10-01 10:13:36
http://php5.kiev.ua/manual/ru/function.realpath.html
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.
2022-03-16 20:12:45
http://php5.kiev.ua/manual/ru/function.realpath.html
Sven Arduwie answer is not tested and does not replicate the behavior of realpath but is a close solution.

This has been unit tested to be as close to realpath as possible but without the path having to actually exist in the system.

This takes relative paths and realizes them properly based on actual current working directory, but everything can be virtual. eg.  "../someVirtualDir/./virtualFile.jpg"

<?php

   
public static function virtualpath($path): string
   
{
       
$path str_replace(['/''\\'], DIRECTORY_SEPARATOR$path);
       
$len strlen($path);
       
$relative strpos($pathDIRECTORY_SEPARATOR);
        if (!
$len || ($len && $path[0] == '.') || $relative !== 0) {
           
$path getcwd() . DIRECTORY_SEPARATOR $path;
        }
       
$parts array_filter(explode(DIRECTORY_SEPARATOR$path), 'strlen');
       
$absolutes = [];
        foreach (
$parts as $part) {
            if (
'.' == $part) {
                continue;
            }
            if (
'..' == $part) {
               
array_pop($absolutes);
            } else {
               
$absolutes[] = $part;
            }
        }
        return 
DIRECTORY_SEPARATOR implode(DIRECTORY_SEPARATOR$absolutes);
    }

?>
2023-01-04 08:58:58
http://php5.kiev.ua/manual/ru/function.realpath.html

    Поддержать сайт на родительском проекте КГБ