TomNomNom.com

Blogging since 2008 until 2010

Real-ish paths without realpath()

Every once in a while you might find the need to resolve the 'double dots' in a file path, but if the file doesn't exist (perhaps you are about to create the file) you can't use PHP's realpath().

If all you want to do is resolve the 'double dots' in a path, you could do so like this:

<?php
function resolveFilename($filename)
{
    $filename = str_replace('//''/'$filename);
    $parts = explode('/'$filename);
    $out = array();
    foreach ($parts as $part){
        if ($part == '.'continue;
        if ($part == '..') {
            array_pop($out);
            continue;
        }
        $out[] = $part;
    }
    return implode('/'$out);
}

assert(resolveFilename('/srv/home/../../etc/./passwd'== '/etc/passwd');
assert(resolveFilename('/srv/home/foo'== '/srv/home/foo');
assert(resolveFilename('../../foo'== 'foo');
assert(resolveFilename('/foo//bar'== '/foo/bar');
assert(resolveFilename('bar'== 'bar');

Note that it is unable to resolve pathnames any higher than the present working directory. I.E. It doesn't know about any directory names that you don't tell it about; hence: ../../foo becomes foo.

The alternative would be to touch() the file, call realpath() and then unlink() the file. Something about that just feels dirty though - you have to be careful with the unlink() step, and if you don't want to resolve symlinks it won't do you any good.

First posted: Wed, 30 Jun 2010 11:11:08 +0000