Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
PHP: realpath - Manual
[go: Go Back, main page]

PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

rename" width="11" height="7"/> <readlink
Last updated: Sun, 25 Nov 2007

view this page in

realpath

(PHP 4, PHP 5)

realpath — 絶対パス名を返す

説明

string realpath ( string $path )

realpath() は、 入力 path のシンボリックリンクをすべて展開し、 「/./」「/../」「/」などの参照をすべて解決することにより、正規化した絶対パスを返します。

パラメータ

path

調べたいパス。

返り値

成功した場合は正規化した絶対パス名を返します。 返されるパスはシンボリックリンクや「/./」「/../」要素を含みません。

realpath() は、 たとえばファイルが存在しないなどの失敗時に FALSE を返します。 BSD システムでは realpath() は最後の path コンポーネントのみが存在しない場合には 失敗となりません。一方、他のシステムではそのような場合にも FALSE を返します。

Example#1 realpath() の例

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

上の例の出力は以下となります。

/etc/passwd



rename" width="11" height="7"/> <readlink
Last updated: Sun, 25 Nov 2007
 
add a note add a note User Contributed Notes
realpath
Zach Bernal zbernal at ucsc dot edu
18-Oct-2007 03:10
Santosh Patnaik's method worked in most cases, but when I gave it funky input with different directory separators it returned the wrong path. I liked julabz at laposte dot net the best, and modified it to use a similar signiture signature to Patnaik's function:

<?php

   
function unrealpath($start_dir, $final_dir, $dirsep = DIRECTORY_SEPARATOR){
       
       
//Directory separator consistency
       
$start_dir = str_replace('/',$dirsep,$start_dir);
       
$final_dir = str_replace('/',$dirsep,$final_dir);
       
$start_dir = str_replace('\\',$dirsep,$start_dir);
       
$final_dir = str_replace('\\',$dirsep,$final_dir);

       
//'Splode!
       
$firstPathParts = explode($dirsep, $start_dir);
       
$secondPathParts = explode($dirsep, $final_dir);
      
       
//Get the number of parts that are the same.
       
$sameCounter = 0;
        for(
$i = 0; $i < min( count($firstPathParts), count($secondPathParts) ); $i++) {
            if(
strtolower($firstPathParts[$i]) !== strtolower($secondPathParts[$i]) ) {
                break;
            }
           
$sameCounter++;
        }
       
//If they do not share any common directories/roots, just return 2nd path.
       
if( $sameCounter == 0 ) {
            return
$final_dir;
        }
       
//init newpath.
       
$newPath = '';
       
//Go up the directory structure count(firstpathparts)-sameCounter times (so, go up number of non-matching parts in the first path.)
       
for($i = $sameCounter; $i < count($firstPathParts); $i++) {
            if(
$i > $sameCounter ) {
               
$newPath .= $dirsep;
            }
           
$newPath .= "..";
        }
       
//if we did not have to go up at all, we're still in start_dir.
       
if( strlen($newPath) == 0 ) {
           
$newPath = ".";
        }
       
//now we go down as much as needed to get to final_dir.
       
for($i = $sameCounter; $i < count($secondPathParts); $i++) {
           
$newPath .= $dirsep;
           
$newPath .= $secondPathParts[$i];
        }
       
//
       
return $newPath;
    }

?>

The only error I found in julabz's function was that count is always 1 for any string, but strlen does what he intended in this case.
cjunge at author-it dot com
16-Oct-2007 08:18
eric at themepark dot com noted that realpath() strips off the trailing directory separator. This is only correct for PHP4!

PHP5 seems to have silently "corrected" this behaviour, now leaving the trailing separator. This can result in incorrect behaviour if your path isn't meant to contain a trailing separator.

eg:
PHP4: realpath("some/path/with/a/trailing/slash/") => "[root]/some/path/with/a/trailing/slash"

PHP5: realpath("some/path/with/a/trailing/slash/") => "[root]/some/path/with/a/trailing/slash/"
alex at bartl dot net
04-Oct-2007 12:25
Sometimes it is helpful to check for the existance of a file
which might be found by using the include_path like in

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.

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
22-Sep-2007 04: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
21-Aug-2007 02: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 06:52
Given real paths of two files, this function finds the relative path of one ($dest) with respect to the other ($root).

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;
}
fornous at sidsolutions dot cz
09-Aug-2007 11:22
The function seems to work only with real path - it also checks whether given file or path exists on windows platform (not sure what it does on Linux).
In case the path is not real the function returns FALSE. I expected the function only convert path into canonical form and lets user decide whether the path exists in filesystem. I would expect the notice at least.
berglov1 at hotmail dot com
24-Jul-2007 11: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
17-Jul-2007 03: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
26-Jun-2007 03: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).

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;
}
adyballa at klingbim dot de
29-May-2007 12:55
I have also a short solution.
But Im not sure, if it is performant.
Explode-Array solution seems to work very fast.

 function buildRelativePath($path){
     $oldP = "";
     $newP = $path;
     while($newP!=$oldP){
         $oldP = $newP;
         $newP = preg_replace("/([^\/]+\/)([^\/]+\/)(\.\.\/)/ms","$1",$newP);
    }
         return str_replace("//","",str_replace("./","",$newP));
 }
Sebastian
18-May-2007 09:00
Who ever wrote the rp()-function. First of all, your function skips filenames or directories with "0" because you use == instead of === when comparing to an "empty" value. Second, the idea of realpath() isn't fixing useless "../" etc, but to resolve the full path of a relative directory/file or a symbolic link. So that if you run the script in '/usr/local/apache2/htdocs/' and exec realpath('uploads/test.txt') the output becomes '/usr/local/apache2/htdocs/uploads/test.txt' (as in the example)

I also wonder why the implementations aren't using the DIRECTORY_SEPARATOR constant and expect Unix.
Marc Noirot
04-May-2007 12:31
Yet another realpath replacement:

function myRealPath($path) {
    // Check if path begins with "/". => use === with strpos
    if (strpos($path,"/") === 0) {
        $path = $_SERVER['DOCUMENT_ROOT'].$path;
    }
    else {
        // Strip slashes and convert to arrays.
        $currentDir = preg_split("/\//",dirname($_SERVER['PATH_TRANSLATED']));
        $newDir = preg_split('/\//',$path);
        // Drop one directory from the array for each ".."; add one otherwise.
        foreach ($newDir as $dir) {
            if ($dir == "..")
               array_pop($currentDir);
            elseif ($dir != ".") //test for "." which represents current dir (do nothing in that case)
               array_push($currentDir,$dir);
        }
        // Return the slashes.
        $path = implode($currentDir,"/");
    }
    return $path;
}
02-Mar-2007 01:17
Tyron Madlener said "I just wonder why all the other solutions are so complex and that mine so simple".

Funny.  I wonder why yours is so complex (26 lines, 2 functions) when it can be done in half that (13 lines, 1 function):

function rp($p) {
    $p=explode('/', $p);
    $o=array();
    for ($i=0; $i<sizeof($p); $i++) {
        if (''==$p[$i] || '.'==$p[$i]) continue;
        if ('..'==$p[$i] && $i>0 && '..'!=$o[sizeof($o)-1]) {
            array_pop($o);
            continue;
        }
        array_push($o, $p[$i]);
    }
    return implode('/', $o);
}

With that, this:

print rp("../../xyz.txt")."\n";
print rp("a/b/c/d/../../xyz.txt")."\n";
print rp("a/b/c/d/../..//xyz.txt")."\n";

Prints:

../../xyz.txt
a/b/xyz.txt
a/b/xyz.txt

As expected.
Patrice Vanneufville
13-Feb-2007 08:29
the precedent function does not work all the time : servers sometimes put a slash '/' at the end of $_SERVER['DOCUMENT_ROOT']

// transforme un chemin d'image relatif en chemin html absolu
function htmlpath($relative_path) {
    $realpath = str_replace("\\", "/", realpath($relative_path));
    $root = preg_replace(',/$,', '', $_SERVER['DOCUMENT_ROOT']);
    if (strlen($root) && strpos($realpath, $root)===0)
        return substr($realpath, strlen($root));
    $dir = dirname(!empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] :
            (!empty($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] :
            (!empty($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : str_replace('\\','/',__FILE__)
        )));
    return canonicalize($dir.'/'.$relative_path);
}

// retourne un chemin canonique a partir d'un chemin contenant des ../
function canonicalize($address) {
    $address = str_replace("//", "/", $address);
    $address = explode('/', $address);
    $keys = array_keys($address, '..');
    foreach($keys as $keypos => $key) array_splice($address, $key - ($keypos * 2 + 1), 2);
    $address = implode('/', $address);
    return preg_replace(',([^.])\./,', '\1', $address);
}
Matthias Fostel
18-Jan-2007 11:52
Popular htmlpath function found below with str_replace to fix issues with PHP on Windows.

function htmlpath($relative_path) {
    $realpath=str_replace("\\", "/", realpath($relative_path));
    $htmlpathURL=str_replace($_SERVER['DOCUMENT_ROOT'],'',$realpath);
    return $htmlpathURL;
}
David Beck
23-Nov-2006 12: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
22-Sep-2005 03: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/
Jonny Rylands
15-Sep-2005 07:19
Having problems with includes within include files,
particularly when the include files are in different directories?

This syntax allows:

* relative paths to be used in include strings.
* include files to include other files in different directories.

without getting file not found errors.

<?
 
include_once realpath(dirname(__FILE__)."/relative/path/to/include.inc.php");
?>
Tyron Madlener
15-Aug-2005 04:53
None of the functions provided here worked for me. All of them somehow had the problem with pathes like '../../downloads/bar/../foo/..' or didn't provide relative paths.
So I coded my one that justs removes '.'-dirs from the paths and simplifies stuff like 'dir/..'

function SimplifyPath($path) {
  $dirs = explode('/',$path);

  for($i=0; $i<count($dirs);$i++) {
    if($dirs[$i]=="." || $dirs[$i]=="") {
      array_splice($dirs,$i,1);
      $i--;
    }

    if($dirs[$i]=="..") {
      $cnt = count($dirs);
      $dirs=Simplify($dirs, $i);
      $i-= $cnt-count($dirs);
    }
  }
  return implode('/',$dirs);
}

function Simplify($dirs, $idx) {
  if($idx==0) return $dirs;

  if($dirs[$idx-1]=="..") Simplify($dirs, $idx-1);
  else  array_splice($dirs,$idx-1,2);

  return $dirs;
}

I just wonder why all the other solutions are so complex and that mine so simple, because in general the problem of simplifieng isn't that hard to solve. Well, I hope that there aren't any cases on which my solution fails. Otherwise, feel free to improve :D
phpnote at web-milk dot co dot uk
22-Jul-2005 11:01
I have written this function so that it does not matter whether the folder exists on the system.  It simply traverses the given path moving up directories at every "/.." that it encounters.  Though this can be used with a file at the end I would be cautious about using it with a query attached as any "/.." in the query will remove the text proir until the previous "/".

<?php
function htmlpath($relative_path)
{
       
$realpath = '';
       
$q = 0;

       
// Remove any ./
       
$relative_path = str_replace('/./', '/', $relative_path);
       
// Remove trailing /
       
if ($relative_path[strlen($relative_path)-1] == '/')
        {
               
$relative_path = substr($relative_path, 0, -1);
        }

       
$p = strpos($relative_path, '/..', $q);
        while (
$p !== false)
        {
               
// Get the next part of the path
               
if ($p != $q) $realpath .= substr($relative_path, $q, $p);

               
// Find the edge of the previous directory
               
$i = strrpos($realpath, '/');
                if (
$i === false)
                {
                        return
false;   // Not enough directories to go up any further.
               
}

               
// Remove the directory
               
$realpath = substr($realpath, 0, $i);
               
// Take out the "/.."
               
$relative_path = substr($relative_path, 0, $p) . substr($relative_path, $p+3);

               
// Find the next "/.."
               
$q = $p;
               
$p = strpos($relative_path, '/..', $q);
        }

       
// Get the rest of the relative path.
       
$realpath .= substr($relative_path, $q);
        return
$realpath;
}
?>
php.netatjulian-lemburg.de
21-Jul-2005 12: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>
09-Jun-2005 02: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
21-Dec-2004 06: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 08: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
20-Nov-2004 02: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.
ilgarm -at- azeronline.com
12-Mar-2004 04: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
18-Jul-2002 10: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
06-Jul-2001 07: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
29-Aug-2000 04: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 ;)

rename" width="11" height="7"/> <readlink
Last updated: Sun, 25 Nov 2007
 
 
show source | credits | sitemap | contact | advertising | mirror sites