1

Before i make my question I wanna say that I have tried every related post I found from stackoverflow such as PHP - Convert File system path to URL and nothing worked for me, meaning I did not get the Url I was looking for.

I need a

function PathToUrl($path) 
{
 ... 
}  

which returns the actual Url of the $path

Example usage: echo PathToUrl('../songs'); should output http://www.mywebsite.com/files/morefiles/songs.

Note: The problem with the functions i found on stackoverflow is that they dont work with path that contains ../ for example on echo PathToUrl('../songs'); i would get something similar to http://www.mywebsite.com/files/morefiles/../songs which is not what i am looking for.

Community
  • 1
  • 1
rez
  • 107
  • 2
  • 13
  • From my experience, you need to use a combination of `$_SERVER['REQUEST_URI']` with realpath(__FILE__) to determine the location of that file in combination with where the path reflects on the address bar. In your case, the answer could be as simple as explode() on the / , and then remove from the end of the array as many items you wish to ../ to, then implode(). – Kraang Prime Sep 27 '14 at 20:59
  • It doesn't work that way from what i have seen... its more complicated – rez Sep 27 '14 at 21:02
  • yes thats the problem , the `../` , i was thinking someone has already implemented a similar function, because creating something like this from zero would take a lot of effort and time , its pretty hard actually – rez Sep 27 '14 at 21:05

2 Answers2

2

Here you go, I made this function and it works perfectly:

function getPath($path)
{
    $url = "http".(!empty($_SERVER['HTTPS'])?"s":"").
        "://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    $dirs = explode('/', trim(preg_replace('/\/+/', '/', $path), '/'));
    foreach ($dirs as $key => $value)
        if (empty($value))  unset($dirs[$key]);
    $parsedUrl = parse_url($url);
    $pathUrl = explode('/', trim($parsedUrl['path'], '/'));
    foreach ($pathUrl as $key => $value)
        if (empty($value))  unset($pathUrl[$key]);
    $count = count($pathUrl);
    foreach ($dirs as $key => $dir)
        if ($dir === '..')
            if ($count > 0)
                array_pop($pathUrl);
            else
                throw new Exception('Wrong Path');
        else if ($dir !== '.')
            if (preg_match('/^(\w|\d|\.| |_|-)+$/', $dir)) {
                $pathUrl[] = $dir;
                ++$count;
            }
            else
                throw new Exception('Not Allowed Char');
    return $parsedUrl['scheme'].'://'.$parsedUrl['host'].'/'.implode('/', $pathUrl);
}

Example:

Let's say your current location is http://www.mywebsite.com/files/morefiles/movies,


echo getPath('../songs');

OUTPUT

http://www.mywebsite.com/files/morefiles/songs

echo getPath('./songs/whatever');

OUTPUT

http://www.mywebsite.com/files/morefiles/movies/songs/whatever

echo getPath('../../../../../../');

In this case it will throw an exception.


NOTE

I use this regex '/^(\w|\d|\.| |_|-)+$/' to check the path directories which mean that only digit, word characters, '.', '-', '_' and ' ' are allowed. An exception will be trown for others characters.

The path .///path will be corrected by this function.

USEFUL

Adam Sinclair
  • 1,654
  • 12
  • 15
  • um , atually, it doesnt work with `../` :S `echo getPath('../song');` gave me `http://www.mywebsite.com/files/morefiles/movies/song` – rez Sep 27 '14 at 22:03
  • ok , i am holding on to that , because i get an `Uncaught exception 'Exception' with message 'Not Allowed Char' ` – rez Sep 27 '14 at 22:09
  • @Shiro I edited my function, it should work. By the way I made this exception. It means you passed a string with a character not allowed like `../song<` – Adam Sinclair Sep 27 '14 at 22:19
  • i dont know why but i get `Fatal error: Uncaught exception 'Exception' with message 'Not Allowed Char' in /home4/shiro/public_html/scr/add/index.php:199 Stack trace: #0 /home4/shiro/public_html/scr/add/index.php(234): PathToUrl('../mp3s/U-Recke...') #1 /home4/shiro/public_html/scr/add/index.php(258): ShowDirectories() #2 {main} thrown in /home4/shiro/public_html/scr/add/index.php on line 199` – rez Sep 27 '14 at 22:22
  • What did you pass to the function ? – Adam Sinclair Sep 27 '14 at 22:24
  • I passed this `../mp3s` , before it worked but it didnt count the `../` it was as if i inputed `/mp3s` – rez Sep 27 '14 at 22:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/62051/discussion-between-adam-sinclair-and-shiro). – Adam Sinclair Sep 27 '14 at 22:28
1

I see an answer was already posted, however I will post my solution which allows for direct specification of the URL :

echo up('http://www.google.ca/mypage/losethisfolder/',1);

function up($url, $howmany=1) {
    $p = explode('/', rtrim($url, '/'));
    if($howmany < count($p)) {
        $popoff = 0;
        while($popoff < $howmany) {
            array_pop($p);
            $popoff++;
        }
    }
    return rtrim(implode('/', $p), '/') . '/';
}

Following is a much more elegant solution for virtual paths :

$path = '/foo/../../bar/../something/../results/in/skipthis/../this/';

echo virtualpath($path);

function virtualpath($path = null) {
    $loopcount = 0;
    $vpath = $path;
    if(is_null($vpath)) { $vpath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); }
    $vpath = rtrim($vpath,'/') . '/';
    while(strpos($vpath,'../') !== false ) {
        if(substr($vpath,0,4) == '/../') { $vpath = '/'. substr($vpath,4); }
        $vpath = preg_replace('/(\/[\w\d\s\ \-\.]+?\/\.\.\/)/', '/', $vpath );
    }
    return $vpath;
}
Kraang Prime
  • 9,981
  • 10
  • 58
  • 124