Thanks to Sven Arduwie's code (pointed out by Pekka) and some modification, I've built a (hopefully) better implementation:
/**
* This function is to replace PHP's extremely buggy realpath().
* @param string The original path, can be relative etc.
* @return string The resolved path, it might not exist.
*/
function truepath($path){
// attempts to detect if path is relative in which case, add cwd
if(strpos($path,':')===false && (strlen($path)==0 || $path{0}!='/')){
$path=getcwd().DIRECTORY_SEPARATOR.$path;
}
// resolve path parts (single dot, double dot and double delimiters)
$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;
}
}
$path=implode(DIRECTORY_SEPARATOR, $absolutes);
// if file exists and it is a link, use readlink to resolves links
if(file_exists($path) && linkinfo($path)>0)$path=readlink($path);
return $path;
}
NB: Unlike PHP's realpath
, this function does not return false on error; it returns a path which is as far as it could to resolving these quirks.