The Server Pages
:: TSP Menu
- Home
- Authors
- Glossary
- RSS Feed

:: Servers
- CPanel
- Hosting
- Linux
- Windows

:: Webmaster
- Databases
- Design
- PHP
- Search Engines

:: Scripts
- Scripts

:: Documentation
- PHP Manual

:: Other
- Errors & Solutions
- TechPunt
- Wojjie

search for in the

rename> <realpath_cache_size
[edit] Last updated: Sat, 12 May 2012

view this page in

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 return 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



rename> <realpath_cache_size
[edit] Last updated: Sat, 12 May 2012
 
add a note add a note User Contributed Notes realpath
dbags 08-Jan-2012 01:37
If using Windows junction.exe to create a symlink, it seems impossible to get the real path to the file. Even __FILE__ contains the symlinked path, not the actual path of the file.
spam at klickagent dot ch 21-Nov-2011 08:42
realpath() function for relative paths:

$relativePath = '../gallery/index/../../advent11/app/';

$pattern = '/\w+\/\.\.\//';
while(preg_match($pattern,$relativePath)){
    $relativePath = preg_replace($pattern, '', $relativePath);
}

output: '../advent11/app/'
php at keith tyler dot com 18-Oct-2011 12:15
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.
imagiro 21-Sep-2011 02:20
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($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);
}
?>
netmosfera at gmail dot com 13-Apr-2011 09:55
please note that realpath is a performance killer

on my sys listing 100 files with realpath takes 0.2 sec (core2quad 6600 x64 4gbddr2)

in most cases, its better to use getcwd() instead and work with dirname() to resolve ".."
Jrg Wagner 11-Jun-2010 12:35
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\\"
jpic 13-May-2010 12:04
There is no native function that does the opposite.

Pure-php implementation:

<?php
function getRelativePath( $path, $compareTo ) {
       
// clean arguments by removing trailing and prefixing slashes
       
if ( substr( $path, -1 ) == '/' ) {
           
$path = substr( $path, 0, -1 );
        }
        if (
substr( $path, 0, 1 ) == '/' ) {
           
$path = substr( $path, 1 );
        }

        if (
substr( $compareTo, -1 ) == '/' ) {
           
$compareTo = substr( $compareTo, 0, -1 );
        }
        if (
substr( $compareTo, 0, 1 ) == '/' ) {
           
$compareTo = substr( $compareTo, 1 );
        }

       
// simple case: $compareTo is in $path
       
if ( strpos( $path, $compareTo ) === 0 ) {
           
$offset = strlen( $compareTo ) + 1;
            return
substr( $path, $offset );
        }

       
$relative  = array(  );
       
$pathParts = explode( '/', $path );
       
$compareToParts = explode( '/', $compareTo );

        foreach(
$compareToParts as $index => $part ) {
            if ( isset(
$pathParts[$index] ) && $pathParts[$index] == $part ) {
                continue;
            }

           
$relative[] = '..';
        }

        foreach(
$pathParts as $index => $part ) {
            if ( isset(
$compareToParts[$index] ) && $compareToParts[$index] == $part ) {
                continue;
            }

           
$relative[] = $part;
        }

        return
implode( '/', $relative );
    }
?>

Some tests forr phpunit:

<?php
   
static public function getRelativePathProvider(  )  {
        return array(
            array(
               
'/srv/foo/bar',
               
'/srv',
               
'foo/bar',
            ),
            array(
               
'/srv/foo/bar',
               
'/srv/',
               
'foo/bar',
            ),
            array(
               
'/srv/foo/bar/',
               
'/srv',
               
'foo/bar',
            ),
            array(
               
'/srv/foo/bar/',
               
'/srv/',
               
'foo/bar',
            ),
            array(
               
'/srv/foo/bar',
               
'/srv/test',
               
'../foo/bar',
            ),
            array(
               
'/srv/foo/bar',
               
'/srv/test/fool',
               
'../../foo/bar',
            ),
            array(
               
'/srv/mad/xp/mad/model/static/css/uni-form.css',
               
'/srv/mad/xp/liria/',
               
'../mad/model/static/css/uni-form.css',
            ),
        );
    }

   
/**
     * @dataProvider getRelativePathProvider
     */
   
public function testGetRelativePath( $path, $compareTo, $expected ) {
       
$result = getRelativePath( $path, $compareTo );
       
$this->assertEquals( $expected, $result );
    }
?>
roman dot vasicek at email dot cz 03-Dec-2009 09:01
You may want to change script behavior depending on the way how its code is invoked (included by another script / called directly). Following code do the job
<?php
if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
 
// called directly
 
...
} else {
 
// included
 
...
}
?>
hrcerqueira at gmail dot com 01-Dec-2009 04:08
if you just need to resolve a path that is not on your system, or you don't want to chdir to it, a simple regular expression can do the trick:

<?php

$p
= '/cool/yeah/../zzz';

$p = preg_replace('/\w+\/\.\.\//', '', $p);

echo
$p; //outputs /cool/zzz

?>
cory dot mawhorter gmail.com 29-Jul-2009 12:36
<?php

// fixes windows paths...
// (windows accepts forward slashes and backwards slashes, so why does PHP use backwards?
function fix_path($path) {
    return
str_replace('\\','/',$path);
}

// takes two absolute paths and determines if one is a subdirectory of the other
// it doesn't care if it is an immediate child or 10 subdirectories deep...
// use absolute paths for both for best results
function is_child($parent, $child) {
    if(
false !== ($parent = realpath($parent))) {
       
$parent = fix_path($parent);
        if(
false !== ($child = realpath($child))) {
           
$child = fix_path($child);
            if(
substr($child, 0, strlen($parent)) == $parent)
                return
true;
        }
    }
   
    return
false;
}

?>
orssey 16-Apr-2009 01:57
<?php

Class RealPath
{
    private
$ServerPath;
    private
$ScriptPath;
    private
$AddSlashEnd;

    function
__construct()
    {
       
$this->AddSlashEnd = "";
       
       
$this->ServerPath = $_SERVER['DOCUMENT_ROOT'];
       
$this->ScriptPath = substr(dirname($_SERVER['SCRIPT_FILENAME']), strlen($this->ServerPath));
    }
   
    private function
Server($adress)
    {
       
$ThisPath = @realpath($adress);
       
$ThisPathLength = strlen($ThisPath);
   
        return
substr($ThisPath, strlen($this->ServerPath), $ThisPathLength);
    }
   
    public function
Absolute($adress)
    {
        return
$_SERVER['SERVER_NAME'] . $this->Server($adress) . $this->AddSlashEnd;
    }
   
    public function
RelativeServer($adress)
    {
        return
$this->Server($adress) . $this->AddSlashEnd;
    }

    public function
RelativeScript($adress)
    {
       
$ScriptExplode = explode("/", $this->ScriptPath);
       
$ServerExplode = explode("/", $this->Server($adress));
       
       
$TmpCount = $ScriptCount = count($ScriptExplode);
       
$ServerCount = count($ServerExplode);
       
       
$ReturnPath = "";
       
        for(
$i = 1; $i < $TmpCount; $i++)
        {
            if(
$ScriptExplode[$i] == $ServerExplode[$i])
                --
$ScriptCount;
            else
                break;
        }
       
        for(
$i = 1; $i < $ScriptCount; $i++)
           
$ReturnPath .= "/..";

        for(
$i = $TmpCount - $ScriptCount + 1; $i < $ServerCount; $i++)
           
$ReturnPath .= "/" . $ServerExplode[$i];
       
        return
$ReturnPath . $this->AddSlashEnd;
    }

    public function
AddSlash($value)
    {
        if(
is_bool($value))
        {
           
$this->AddSlashEnd = ($value)? "/" : "";
            return
true;
        }
        else
            return
false;
    }
   
}

example:

$ObjectPath = new RealPath;
$ObjectPath->RelativeScript("../a/b../c/d/f../g../h");
info[at]adico.co.il 15-Feb-2009 02:13
for those who want to start realpath on windows platform and looking for example.

OR

for those who want to run zend framework on windows platform using the quick start guide

<?php
define
( "_CUR_OS", substr( php_uname( ), 0, 7 ) == "Windows" ? "Win" : "_Nix" );

function
checkCurrentOS( $_OS )
{
    if (
strcmp( $_OS, _CUR_OS ) == 0 ) {
        return
true;
    }
    return
false;
}

// public/index.php
//
// Step 1: APPLICATION_PATH is a constant pointing to our
// application/subdirectory. We use this to add our "library" directory
// to the include_path, so that PHP can find our Zend Framework classes.

if ( checkCurrentOS( "Win" ) ) {
   
$mappath = '/' . str_replace( "\\", "/", str_replace( "C:\\","", dirname(__FILE__) ) );
}
else {
   
$mappath = dirname(__FILE__);
}

define('APPLICATION_PATH', realpath$mappath . '/../_privateadico/application/') );
set_include_path(
   
APPLICATION_PATH . '/../library'
   
. PATH_SEPARATOR . get_include_path()
);
?>

I took the index.php for zend which is was written for unix and ported it to windows.

The porting problem was with realpath function not understanding dirname(__FILE__) syntex on windows
Isaac Z. Schlueter i at foohack dot com 27-Aug-2008 07:02
If you need to resolve a url against a base url, as the browser does with anchor tags, then realpath won't help, because it's not on your file system.

This function does that:

<?php
function resolve_href ($base, $href) {
     
   
// href="" ==> current url.
   
if (!$href) {
        return
$base;
    }

   
// href="http://..." ==> href isn't relative
   
$rel_parsed = parse_url($href);
    if (
array_key_exists('scheme', $rel_parsed)) {
        return
$href;
    }

   
// add an extra character so that, if it ends in a /, we don't lose the last piece.
   
$base_parsed = parse_url("$base ");
   
// if it's just server.com and no path, then put a / there.
   
if (!array_key_exists('path', $base_parsed)) {
       
$base_parsed = parse_url("$base/ ");
    }

   
// href="/ ==> throw away current path.
   
if ($href{0} === "/") {
       
$path = $href;
    } else {
       
$path = dirname($base_parsed['path']) . "/$href";
    }

   
// bla/./bloo ==> bla/bloo
   
$path = preg_replace('~/\./~', '/', $path);

   
// resolve /../
    // loop through all the parts, popping whenever there's a .., pushing otherwise.
       
$parts = array();
        foreach (
           
explode('/', preg_replace('~/+~', '/', $path)) as $part
       
) if ($part === "..") {
           
array_pop($parts);
        } elseif (
$part!="") {
           
$parts[] = $part;
        }

    return (
        (
array_key_exists('scheme', $base_parsed)) ?
           
$base_parsed['scheme'] . '://' . $base_parsed['host'] : ""
   
) . "/" . implode("/", $parts);

}
?>

[EDIT BY danbrown AT php DOT net:  Code contains a bugfix supplied by (Zhenya DOT Morozov AT gmail DOT com) on 23-JAN-09, to address the following issue:
'If your path contains "0" (or any "false" string) directory name, the function removes that directory from the path.']
Sven Arduwie 23-Jun-2008 03:43
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. :)
waldemar dot axdorph at gmail dot com 08-Jun-2008 08:49
I made this function so that I could see if a user was trying to go above the current directory.

My top dir:
/var/www/dir/

User wanted
/var/www/

This comes in handy when you're making a php explorer/filemanager and you want your files in the directory above to be private.

Here it is

<?php
//usage
//$dir is the dir you are in
//$dir_top is the highest dir allowed.

//example
/*
if(above_dir('../', '/var/www/filemgr'))
    die('Not allowed. Please stick to your directories');
*/
function above_dir($dir, $dir_top){
    if(
$dir == $dir_top)
        return
false;
   
   
$dir = realpath($dir);
   
$dir_top = realpath($dir_top);
   
   
$dir = count(explode('/', $dir));
   
$dir_top = count(explode('/', $dir_top));
   
    if(
$dir <= $dir_top){
        return
true;
    }else{
        return
false;
    }
}

?>
rlee at excel dot com 24-Apr-2008 03:21
Some users will notice that PHP applications malfunction when they upgrade to PHP 5.2.4 (included in Ubuntu 8.04 LTS) because realpath returns true for files that don't exist.

This is due to the inclusion of the Hardened-PHP Project's Suhosin Patch in many distributions by default. This patch replaces PHPs realpath function with the BSD implementation, which ignores the last path component.

The workaround is to use the file_exists function to verify that the file exists before using realpath to get its real path string.

e.g: instead of:

<?php

if (realpath($path)) {
   
$path = realpath($path);
} else {
    throw new
Exception('Path not found!');
}
 
?>

Do this:

<?php

if (file_exists($path)) {
   
$path = realpath($path);
} else {
    throw new
Exception('Path not found!');
}
 
?>

See http://www.hardened-php.net/suhosin/a_feature_list:realpath.html
131 dot php at cloudyks dot org 19-Mar-2008 05:34
<?php
//rp like, working with absolute/relative path & a little bit shorter :p

function rp($path) {
   
$out=array();
    foreach(
explode('/', $path) as $i=>$fold){
        if (
$fold=='' || $fold=='.') continue;
        if (
$fold=='..' && $i>0 && end($out)!='..') array_pop($out);
    else
$out[]= $fold;
    } return (
$path{0}=='/'?'/':'').join('/', $out);
}
?>
alex at bartl dot net 03-Oct-2007 08:25
Sometimes it is helpful to check for the existance of a file
which might be found by using the include_path like in

<?php
include("file_from_include_path.php");
?>

A simple function iterates the include_path and tries all
possibilites, returns translated_local_path on success or false
if not found.

<?php
function mappath($path_to_translate){
 
$IncludePath=explode(PATH_SEPARATOR,get_include_path());
  foreach(
$IncludePath as $prefix){
    if(
substr($prefix,-1)==DIRECTORY_SEPARATOR)
     
$prefix=substr($prefix,0,-1);
   
$try_path=sprintf("%s%s%s"
     
,$prefix,DIRECTORY_SEPARATOR,$path_to_translate);
    if(
file_exists($try_path))return($try_path);
  }
  return
false;
}
?>
alban dot lopez+php dot net at gmail dot com 21-Sep-2007 12:15
Here's a little function to return the shortest relative path between dest folder and current folder (you can be replace $_SERVER['PHP_SEFL'] by your variable folder) :

<?php
// if you run in /var/www/

echo UnRealPath ('./'); // return "./"
echo UnRealPath ('./ajax-browser/AJAX-B/scripts/'); // return "./ajax-browser/AJAX-B/scripts/"
echo UnRealPath ('/var/'); // return "./../"
echo UnRealPath ('/opt/picasa/wine/'); // return "./../../opt/picasa/wine/"

function UnRealPath ($dest)
{
   
$Ahere = explode ('/', realpath($_SERVER['PHP_SEFL']));
   
$Adest = explode ('/', realpath($dest));
   
$result = '.'; // le chemin retoun√© dois forcement commanc√© par ./   c'est le but
   
while (implode ('/', $Adest) != implode ('/', $Ahere))// && count ($Adest)>0 && count($Ahere)>0 )
   
{
        if (
count($Ahere)>count($Adest))
        {
           
array_pop($Ahere);
           
$result .= '/..';
        }
        else
        {
           
array_pop($Adest);
        }
    }
    return
str_replace('//', '/', $result.str_replace(implode ('/', $Adest), '', realpath($dest)).(@is_dir(realpath($dest))?'/':''));
}
?>
viaujoc at videotron dot ca 20-Aug-2007 10:50
Beware that the use of a NULL value for the $path argument will give different results depending on the platform:

On Windows, realpath(null) will return the current path (same as realpath(".")).

On Linux (tested on Kernel 2.6) it will return FALSE.
Santosh Patnaik 20-Aug-2007 02:52
Given real paths of two files, this function finds the relative path of one ($dest) with respect to the other ($root).

<?php
echo rel_path('a/b/c', 'd/e'); // './../../a/b/c'
echo rel_path('a/b/c', 'a/b/c/d/e'); // './../..'
echo rel_path('a/b/c/d/e', 'a/b/c'); // './d/e'

function rel_path($dest, $root = '', $dir_sep = '/')
{
 
$root = explode($dir_sep, $root);
 
$dest = explode($dir_sep, $dest);
 
$path = '.';
 
$fix = '';
 
$diff = 0;
 for(
$i = -1; ++$i < max(($rC = count($root)), ($dC = count($dest)));)
 {
  if(isset(
$root[$i]) and isset($dest[$i]))
  {
   if(
$diff)
   {
   
$path .= $dir_sep. '..';
   
$fix .= $dir_sep. $dest[$i];
    continue;
   }
   if(
$root[$i] != $dest[$i])
   {
   
$diff = 1;
   
$path .= $dir_sep. '..';
   
$fix .= $dir_sep. $dest[$i];
    continue;
   }
  }
  elseif(!isset(
$root[$i]) and isset($dest[$i]))
  {
   for(
$j = $i-1; ++$j < $dC;)
   {
   
$fix .= $dir_sep. $dest[$j];
   }
   break;
  }
  elseif(isset(
$root[$i]) and !isset($dest[$i]))
  {
   for(
$j = $i-1; ++$j < $rC;)
   {
   
$fix = $dir_sep. '..'. $fix;
   }
   break;
  }
 }
  return
$path. $fix;
}
?>
berglov1 at hotmail dot com 24-Jul-2007 07:22
There might be other solutions like mine in here,
but here is one more.

This function converts Virtual Paths into Relative Paths.
I needed that at one time, and I did'nt have much luck finding a solution amongst the PHP Functions in the manual.

<?php
function GetPath($RedPath) {

  if(
substr($RedPath, 0, 1) == "/") {
   
$SysPath = dirname($_SERVER['PHP_SELF']);

    if(
substr($RedPath, -1) == "/") $RedPath = substr($RedPath, 0, -1);

    if(
strlen($SysPath) == 1)
      return
".".$RedPath;
    elseif(
strcmp($SysPath,$RedPath) == 0)
      return
"./"

    else {
     
$s_tmp = split("/", $SysPath);
     
$r_tmp = split("/", $RedPath);

      while((
$r_tmp[$i] == $s_tmp[$i]) && $i < 10)
       
$i++;

     
$t_RedPath = end(split("/", $RedPath, ($i+1))); 

      if(
$i == count($s_tmp))
        return
"./".$t_RedPath;
      else
        return
str_repeat("../", count($s_tmp)-$i).$t_RedPath;
    }
  }
  else
    return
$RedPath;

}
?>
julabz at laposte dot net 16-Jul-2007 11:49
Here's a little function to return the relative path between two urls:

<?php

   
function get_relative_path($start_dir, $final_dir){
       
//
       
$firstPathParts = explode(DIRECTORY_SEPARATOR, $start_dir);
       
$secondPathParts = explode(DIRECTORY_SEPARATOR, $final_dir);
       
//
       
$sameCounter = 0;
        for(
$i = 0; $i < min( count($firstPathParts), count($secondPathParts) ); $i++) {
            if(
strtolower($firstPathParts[$i]) !== strtolower($secondPathParts[$i]) ) {
                break;
            }
           
$sameCounter++;
        }
        if(
$sameCounter == 0 ) {
            return
$final_dir;
        }
       
//
       
$newPath = '';
        for(
$i = $sameCounter; $i < count($firstPathParts); $i++) {
            if(
$i > $sameCounter ) {
               
$newPath .= DIRECTORY_SEPARATOR;
            }
           
$newPath .= "..";
        }
        if(
count($newPath) == 0 ) {
           
$newPath = ".";
        }
        for(
$i = $sameCounter; $i < count($secondPathParts); $i++) {
           
$newPath .= DIRECTORY_SEPARATOR;
           
$newPath .= $secondPathParts[$i];
        }
       
//
       
return $newPath;
    }

?>
richpageau at yahoo dot co dot uk 25-Jun-2007 11:55
This is my attempt at writing a realpath replacement. I needed to to run some Adobe code on a server with realpath disabled and this seemed to do the job. It is written for a unix server, I suppose it could be made cross platform using DIRECTORY_SEPARATOR. (With thanks to Marc Noirot for his code).

<?php
function myRealPath($path) {

   
// check if path begins with "/" ie. is absolute
    // if it isnt concat with script path
   
if (strpos($path,"/") !== 0) {
       
$base=dirname($_SERVER['SCRIPT_FILENAME']);
       
$path=$base."/".$path;
    }
 
   
// canonicalize
   
$path=explode('/', $path);
   
$newpath=array();
    for (
$i=0; $i<sizeof($path); $i++) {
        if (
$path[$i]==='' || $path[$i]==='.') continue;
           if (
$path[$i]==='..') {
             
array_pop($newpath);
              continue;
        }
       
array_push($newpath, $path[$i]);
    }
   
$finalpath="/".implode('/', $newpath);

   
// check then return valid path or filename
   
if (file_exists($finalpath)) {
        return (
$finalpath);
    }
    else return
FALSE;
}
?>
David Beck 22-Nov-2006 07:38
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 * 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

?>
bart at mediawave dot nl 21-Sep-2005 11:31
Here's another function that resolves references to '/./', '/../' and extra '/' characters in the input path and returns the canonicalized pathname.

<?php

function cleanPath($path) {
   
$result = array();
   
// $pathA = preg_split('/[\/\\\]/', $path);
   
$pathA = explode('/', $path);
    if (!
$pathA[0])
       
$result[] = '';
    foreach (
$pathA AS $key => $dir) {
        if (
$dir == '..') {
            if (
end($result) == '..') {
               
$result[] = '..';
            } elseif (!
array_pop($result)) {
               
$result[] = '..';
            }
        } elseif (
$dir && $dir != '.') {
           
$result[] = $dir;
        }
    }
    if (!
end($pathA))
       
$result[] = '';
    return
implode('/', $result);
}

echo
'input:  ', $path = '..//./../dir4//./dir5/dir6/..//dir7/', '<br />';
echo
'output: ', cleanPath($path), '<br />';

?>

Will return:

input:  ..//./../dir4//./dir5/dir6/..//dir7/
output: ../../dir4/dir5/dir7/
php.netatjulian-lemburg.de 20-Jul-2005 08:55
You have a realpath.
Now you want a htmlpath.

First Suggestion:
<?php

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

But this does not work on some servers.

Second Suggestion:

<?php

function htmlpath($realpath) {
  
$i = substr_count($_ENV["SCRIPT_URL"],'/')."<br>";
  
$baserealpath=realpath(str_repeat('../',$i-1));
  
$htmlpath=str_replace($baserealpath,'',$realpath);
   return
$htmlpath;
}

?>
Lars Scheithauer <l dot scheithauer at gmx dot de> 08-Jun-2005 10:44
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.
pulstar at ig dot com dot br 20-Dec-2004 01:43
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>
eric at themepark dot com 17-Jul-2002 06:15
note that realpath() will chop any trailing delimiter like \ or / ...don't forget to add it back on if you need it.

Eric Mueller - themepark.com
jemptyg at rwmc dot net 05-Jul-2001 03:38
realpath() seems to be equivalent to ASP's Server.MapPath.  On my Win2k box I have successfully used realpath() to give me the full path for a file outside of the document_root.  This will be very useful in conjunction with is_dir and/or is_file, which require a full path.
jerome at dot451 dot com 28-Aug-2000 12:03
mkdir (and realpath) did not work because i'd used virtual() function to replace server side include in my file.
And i've just seen that virtual() function changes the current directory ... that's why !

jerome ;)

 
show source | credits | sitemap | contact | advertising | mirror sites