search for in the  
<readlinkrename>
Last updated: Thu, 19 May 2005

realpath

(PHP 4, PHP 5)

realpath -- Returns 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. The resulting path will have no symbolic link, '/./' or '/../' components.

realpath() returns FALSE on failure, e.g. if the file does not exists.

Example 1. realpath() example

<?php
$real_path
= realpath("../../index.php");
?>

See also basename(), dirname(), and pathinfo().



User Contributed Notes
realpath
pulstar at ig dot com dot br
20-Dec-2004 03: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>
carlosreche at yahoo dot com
16-Dec-2004 05:52
In my last function, it will always discard "../" if there are no more parent dirs to go back. But it's a mistake! For example, relative paths like "../../downloads" returns "downloads/", and it should return exactly the same entry (because parent directories for "downloads" may exist in this case). Well, I've corrected this bug. Now:

"C:/downloads/../../../" returns "C:/"
"downloads/../../../"  returns  "../../"

<?php

function real_path($path)
{
   if (
$path == "")
   {
       return
false;
   }

  
$path = trim(preg_replace("/\\\\/", "/", (string)$path));

   if (!
preg_match("/(\.\w{1,4})$/", $path)  && 
       !
preg_match("/\?[^\\/]+$/", $path)  && 
       !
preg_match("/\\/$/", $path))
   {
      
$path .= '/';
   }

  
$pattern = "/^(\\/|\w:\\/|https?:\\/\\/[^\\/]+\\/)?(.*)$/i";

  
preg_match_all($pattern, $path, $matches, PREG_SET_ORDER);

  
$path_tok_1 = $matches[0][1];
  
$path_tok_2 = $matches[0][2];

  
$path_tok_2 = preg_replace(
                   array(
"/^\\/+/", "/\\/+/"),
                   array(
"", "/"),
                  
$path_tok_2);

  
$path_parts = explode("/", $path_tok_2);
  
$real_path_parts = array();

   for (
$i = 0, $real_path_parts = array(); $i < count($path_parts); $i++)
   {
       if (
$path_parts[$i] == '.')
       {
           continue;
       }
       else if (
$path_parts[$i] == '..')
       {
           if (  (isset(
$real_path_parts[0])  &&  $real_path_parts[0] != '..')
               || (
$path_tok_1 != "")  )
           {
              
array_pop($real_path_parts);
               continue;
           }
       }

      
array_push($real_path_parts, $path_parts[$i]);
   }

   return
$path_tok_1 . implode('/', $real_path_parts);
}

?>
ash at spamless dot theleys dot net
19-Nov-2004 11:37
sarizmendi is right, and this is very frustrating. I'm trying to use a script with a different virtual root, which process folders/contents. This works perfectly with asp's server.mappath() but realpath() fails, because it's mapping to the same doc root (C:\inetpub\wwwroot) when it should be from a different virtual path (i.e. D:\content). Although I could force this to the static path, I'm trying to use it with a $_GET, and this could point to any of a number of virtual roots.
steudel at attenstion dot de
20-Oct-2004 12:38
I just mentioned a quite confusing aspect of realpath(). Suppose a path '/my/existing/path' that really exists and a path '/my/existing/path/nonexistentsubdir' that doesn't. A call to
<?php
realpath
('/my/existing/path/nonexistentsubdir/..');
?>
will fail because it contains a non-existent path.

watch out! ;-)
ilgarm -at- azeronline.com
11-Mar-2004 01:43
I've tested several examples given by other ppls but none were working, at least on windows. so I spent time and wrote my own function for realpath( ) replacement that will work with non-existing paths also.
Here it is. Please, check it, if you have time and let me know about the results. Thanks.

<?php

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

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

function
isRelative( $_dir )
{
   if (
checkCurrentOS( "Win" ) ) {
       return (
preg_match( "/^\w+:/", $_dir ) <= 0 );
   }
   else {
       return (
preg_match( "/^\//", $_dir ) <= 0 );
   }
}

function
unifyPath( $_path )
{
   if (
checkCurrentOS( "Win" ) ) {
       return
str_replace( "\\", _PL_OS_SEP, $_path );
   }
   return
$_path;
}

function
getRealpath( $_path )
{
  
/*
     * This is the starting point of the system root.
     * Left empty for UNIX based and Mac.
     * For Windows this is drive letter and semicolon.
     */
  
$__path = $_path;
   if (
isRelative( $_path ) ) {
      
$__curdir = unifyPath( realpath( "." ) . _PL_OS_SEP );
      
$__path = $__curdir . $__path;
   }
  
$__startPoint = "";
   if (
checkCurrentOS( "Win" ) ) {
       list(
$__startPoint, $__path ) = explode( ":", $__path, 2 );
      
$__startPoint .= ":";
   }
  
# From now processing is the same for WIndows and Unix, and hopefully for others.
  
$__realparts = array( );
  
$__parts = explode( _PL_OS_SEP, $__path );
   for (
$i = 0; $i < count( $__parts ); $i++ ) {
       if (
strlen( $__parts[ $i ] ) == 0 || $__parts[ $i ] == "." ) {
           continue;
       }
       if (
$__parts[ $i ] == ".." ) {
           if (
count( $__realparts ) > 0 ) {
              
array_pop( $__realparts );
           }
       }
       else {
          
array_push( $__realparts, $__parts[ $i ] );
       }
   }
   return
$__startPoint . _PL_OS_SEP . implode( _PL_OS_SEP, $__realparts );
}

echo
"getRealpath ../../x: ". getRealpath( "../../x" ) . "<BR>\n";
echo
"getRealpath ./../x: ". getRealpath( "./../x" ) . "<BR>\n";
echo
"getRealpath x: ". getRealpath( "x" ) . "<BR>\n";
echo
"getRealpath /../x: ". getRealpath( "/../x" ) . "<BR>\n";
echo
"getRealpath d:/../../x: ". getRealpath( "d:/../../x" ) . "<BR>\n";
echo
"getRealpath ./../xx/xxx/.////../yyy: ". getRealpath( "./../xx/xxx/.////../yyy" ) . "<BR>\n";

?>
eric at themepark dot com
17-Jul-2002 08: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 05: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 02: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 ;)

<readlinkrename>
 Last updated: Thu, 19 May 2005
Copyright © 2001-2005 The PHP Group
All rights reserved.
This unofficial mirror is operated at: The Server Pages
Last updated: Thu May 19 17:35:34 2005 CDT