note 35668 deleted from function.realpath by aidan
| From: | aidan@php.net | Date: | Sun, 29 Aug 2004 21:50:30 +0000 |
| Subject: | note 35668 deleted from function.realpath by aidan | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-75607@lists.php.net to get a copy of this message | ||
Note Submitter: jose l dot salinas (jlsalinas dot nosp at m dot gmx dot n)
----
I've got the same problem than Dave and I've made a function that gives the relative path
from one directory (not necessary the script's one) to any file. Both can be absolute or
relative paths.
It's very useful when including files or inserting paths relative to a hidden directory inside
an URL.
I think it would be nice to see a function with this functionality added to the PHP function list.
;)
function relative_path ($targetfile, $basedir = '.') {
$basedir = realpath ($basedir);
$targetfile = realpath ($targetfile);
// on windows, check that both paths are on the same drive
if (substr ($basedir, 0, 1) != substr ($targetfile, 0, 1)) {
return false;
}
// split each path into its directories
$base_parts = split ('\/', str_replace ('\\', '/', $basedir));
$target_parts = split ('\/', str_replace ('\\', '/', $targetfile));
// ensure that there are no empty elements at the end (c:\ would cause it)
for ($i = count($base_parts) - 1; $i >= 0; $i--) {
if ($base_parts[$i] == '') {
unset ($base_parts[$i]);
} else {
break;
}
}
for ($i = count($target_parts) - 1; $i >= 0; $i--) {
if ($target_parts[$i] == '') {
unset ($target_parts[$i]);
} else {
break;
}
}
// get rid of the common directories at the beginning of the paths
$common_count = 0;
for ($i = 0; $i < count($base_parts); $i++) {
if ($target_parts[$i] == $base_parts[$i]) {
$common_count++;
} else {
break;
}
}
for ($i = 0; $i < $common_count; $i++) {
unset ($base_parts[$i]);
unset ($target_parts[$i]);
}
// build the resulting string
return str_repeat ('../', count($base_parts)) . implode ('/', $target_parts);
}
Some usage examples:
echo relative_path ('.', '.');
whould print nothing.
echo relative_path ('file1', '');
whould print "file1.txt".
echo relative_path ('dir1/dir2/file1.txt', 'dir1');
whould print: "dir2/file1.txt"
echo relative_path ('dir1/dir2/file1.txt', 'dir1/dir3');
whould print: "../dir2/file1.txt"
Of course, to get the real file, when calling
$relpath = relative_path ($filepath, $basedir);
you need to compund it:
$goodpath = $basedir . '/' . $relpath;
(we're supposing $basedir's last char wasn't a slash)