macgruder
asked on
Generate an absolute link from a URL plus a link
Given a URL like
http://foo.com/bar
or
http://foo.com/bar.html
or
http://foo.com/bar/
plus a link like
index.html
or
././
or
./
etc.
I want to generate the absolute
get_absolute('http://foo.com/bar/', '../pics/my.gif')
would return
http://foo.com/pics/my.gif
etc.
Needs to be robust for slash issues.
http://foo.com/bar
or
http://foo.com/bar.html
or
http://foo.com/bar/
plus a link like
index.html
or
././
or
./
etc.
I want to generate the absolute
get_absolute('http://foo.com/bar/', '../pics/my.gif')
would return
http://foo.com/pics/my.gif
etc.
Needs to be robust for slash issues.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
It probably also makes sense to check if someone has put in so man ../../.. that it makes it traverse back below your web directory, and to make sure realpath is not false...putting that all together in a function,
function get_real_path($var){
//change these to match your server
$base_path = '/absolute/path/to/www/dir ';
$base_url = 'http://www.yoursite.com';
$var_real = str_replace($base_url, $base_path, $var);
$var_real = realpath($var_real);
if ($var_real === false || strpos($var_real, $base_path) !== 0) return false;
return str_replace($base_path, $base_url, $var_real);
}
function get_real_path($var){
//change these to match your server
$base_path = '/absolute/path/to/www/dir
$base_url = 'http://www.yoursite.com';
$var_real = str_replace($base_url, $base_path, $var);
$var_real = realpath($var_real);
if ($var_real === false || strpos($var_real, $base_path) !== 0) return false;
return str_replace($base_path, $base_url, $var_real);
}
<?php
function get_absolute($baseUrl, $relativeLink)
{
// Getting base scheme, host and path. If base url is not correct
// return false
if (!($base = @parse_url(trim($baseUrl)) )) return false;
// Checking relativeLink
if (1 === preg_match("/\/[^.]+\/\.+/ ", $relativeLink)) return false;
// Parsing relativeLink
$rel = explode("/", trim($relativeLink));
// Now we have to know how deep is relative
$level_up = 0;
$level_root = false;
foreach ($rel as $k => $v)
{
if ("" == $v)
{
unset($rel[$k]);
}
if ("." == $v)
{
$level_root = true;
unset($rel[$k]);
}
if (".." == $v)
{
$level_up++;
unset($rel[$k]);
}
}
$path = "";
if ($level_root)
{
$path = "/" . implode("/", $rel);
}
else
{
$base['path'] = preg_replace("/^\/+/", "", $base['path']);
$base['path'] = preg_replace("/\/+$/", "", $base['path']);
$base['path'] = explode("/", $base['path']);
if ($level_up >= count($base['path']))
{
$path = "/" . implode("/", $rel);
}
else
{
while($level_up != 0)
{
$i = count($base['path']) - 1;
unset($base['path'][$i]);
$level_up--;
}
$path = "/" . implode("/", $base['path']) . "/" . implode("/", $rel);
}
}
return $base['scheme'] . "://" . $base['host'] . $path;
}
echo get_absolute('http://foo.com/bar/', '../pics/my.gif');
?>
function get_absolute($baseUrl, $relativeLink)
{
// Getting base scheme, host and path. If base url is not correct
// return false
if (!($base = @parse_url(trim($baseUrl))
// Checking relativeLink
if (1 === preg_match("/\/[^.]+\/\.+/
// Parsing relativeLink
$rel = explode("/", trim($relativeLink));
// Now we have to know how deep is relative
$level_up = 0;
$level_root = false;
foreach ($rel as $k => $v)
{
if ("" == $v)
{
unset($rel[$k]);
}
if ("." == $v)
{
$level_root = true;
unset($rel[$k]);
}
if (".." == $v)
{
$level_up++;
unset($rel[$k]);
}
}
$path = "";
if ($level_root)
{
$path = "/" . implode("/", $rel);
}
else
{
$base['path'] = preg_replace("/^\/+/", "", $base['path']);
$base['path'] = preg_replace("/\/+$/", "", $base['path']);
$base['path'] = explode("/", $base['path']);
if ($level_up >= count($base['path']))
{
$path = "/" . implode("/", $rel);
}
else
{
while($level_up != 0)
{
$i = count($base['path']) - 1;
unset($base['path'][$i]);
$level_up--;
}
$path = "/" . implode("/", $base['path']) . "/" . implode("/", $rel);
}
}
return $base['scheme'] . "://" . $base['host'] . $path;
}
echo get_absolute('http://foo.com/bar/', '../pics/my.gif');
?>
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks guys. I'm splitting the points. The first led to me generating a solution(before ixti posted) and the second is also a useful solution which I'm going to look at more carefully.
http://us2.php.net/realpath
something like (assuming your variable is in $var)
<?php
//change these to match your server
$base_path = '/absolute/path/to/www/dir
$base_url = 'http://www.yoursite.com';
$var_real = str_replace($base_url, $base_path, $var);
$var_real = realpath($var_real);
$var_real = str_replace($base_path, $base_url, $var_real);
echo $var_real;
?>
This is untested, but should be the right idea.