views:

188

answers:

1

I need a fast and reliable way to map an absolute or relative local path (say ./images/Mafalda.jpg) to it's corresponding absolute URL, so far I've managed to come up with this:

function Path($path)
{
    if (file_exists($path) === true)
    {
        return rtrim(str_replace('\\', '/', realpath($path)), '/') . (is_dir($path) ? '/' : '');
    }

    return false;
}

function URL($path)
{
    $path = Path($path);

    if ($path !== false)
    {
        return str_replace($_SERVER['DOCUMENT_ROOT'], getservbyport($_SERVER['SERVER_PORT'], 'tcp') . '://' . $_SERVER['HTTP_HOST'], $path);
    }

    return false;
}

URL('./images/Mafalda.jpg'); // http://domain.com/images/Mafalda.jpg

Seems to be working as expected, but since this is a critical feature to my app I want to ask if anyone can spot any problem that I might have missed and optimizations are also welcome since I'm going to use this function several times per each request. Anyone?

+1  A: 

One potential issue to look out for is symbolic links. If DOCUMENT_ROOT contains a part that is a symlink, things will blow up (since realpath() will expand that symlink).

Of course, the solution might be as simple as wrapping $_SERVER['DOCUMENT_ROOT'] in realpath() as well.

timdev
That would be a problem indeed, better throw a `is_link()` call in there, thanks. Can you think of any optimizations in order to make it faster?
Alix Axel
Not sure. I'm fairly sure the filesystem-related stuff is going to be the slowest bit. But you need it. The str_replaces should be fast.
timdev
Also: not sure is_link() is the way to go. You'd have to test each part of the path. Probably more sane to just let realpath() do it. As long as you're always dealing with real paths, you know symlinks won't be an issue.
timdev