PHP Script for Converting Relative to Absolute URL

Jun 5, 2009 | Tags: PHP, Regex | del.icio.us del.icio.us | digg Digg

This is a very simple PHP script to convert relative URL to its absolute path, given a base URL. e.g: converting lena.jpg to http://www.example.com/a/b/lena.jpg.

When I searched Google for scripts to convert relative to absolute URL, I came accross a site that has done that, only in Perl. It is a very simple script compared to the others, so I tried to port the code into PHP.

Note what the Perl geek said about this:

"I wrote this mainly because someone asked how to do this in PHP. Turns out there is nothing in like the venerable URI module in all of PHP-dom (how pathetic is that for a language as web-centric as it?)" lol

Btw, here's the script:

Listing 1: rel2abs.php

  1. <?php
  2. function rel2abs($rel, $base)
  3. {
  4.     /* return if already absolute URL */
  5.     if (parse_url($rel, PHP_URL_SCHEME) != '') return $rel;
  6.    
  7.     /* queries and anchors */
  8.     if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel;
  9.    
  10.     /* parse base URL and convert to local variables:
  11.        $scheme, $host, $path */
  12.     extract(parse_url($base));
  13.  
  14.     /* remove non-directory element from path */
  15.     $path = preg_replace('#/[^/]*$#', '', $path);
  16.  
  17.     /* destroy path if relative url points to root */
  18.     if ($rel[0] == '/') $path = '';
  19.    
  20.     /* dirty absolute URL */
  21.     $abs = "$host$path/$rel";
  22.  
  23.     /* replace '//' or '/./' or '/foo/../' with '/' */
  24.     $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
  25.     for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
  26.    
  27.     /* absolute URL is ready! */
  28.     return $scheme.'://'.$abs;
  29. }

The results is shown in the table below, given base URL is http://www.example.com/a/b/c

Table 1. Conversion Results

Relative URL Absolute URL
lena.jpg http://www.example.com/a/b/lena.jpg
./lena.jpg http://www.example.com/a/b/lena.jpg
../lena.jpg http://www.example.com/a/lena.jpg
../../lena.jpg http://www.example.com/lena.jpg
/lena.jpg http://www.example.com/lena.jpg
../x/lena.jpg http://www.example.com/a/x/lena.jpg
../../x/y/lena.jpg http://www.example.com/x/y/lena.jpg
http://google.com http://google.com
../../x/y/lena.jpg http://www.example.com/x/y/lena.jpg
?w=90&h=60&f=lena.jpg http://www.example.com/a/b/c?w=90&h=60&f=lena.jpg
#lena http://www.example.com/a/b/c#lena

Related Articles

Recommended Book

8 Comments

dr.emi on Jun 27, 2009:

Hi! Nashruddin..
Remember me ?

Nice tutorial friend !

Salman on Jun 29, 2009:

Complicated but complete example. You might want to add additional details about how to calculate $base instead of hard-coding it. Something that goes along these lines:

$base = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);

Nash on Jun 29, 2009:

I got your point. but the script is intended to determine the absolute URL of a _remote_ resource, not local resources in our server. It goes like this: say you are writing a bulk downloader to download the images in http://example.com/nature/photos.html. If the links are in relative URLs:

<a href="img/beach.jpg">The Beach</a>
<a href="img/lake.jpg">The Lake</a>
<a href="img/river.jpg">The River</a>


You can use the script above to obtain the absolute URLs:

http://example.com/nature/img/beach.jpg
http://example.com/nature/img/lake.jpg
http://example.com/nature/img/river.jpg

Alex Vincent on Nov 11, 2009:

Bug in the script: ../../../x/y/lena.jpg leads to http://www.example.com/../x/y/lena.jpg

Nash on Jan 29, 2010:

I won't call it a bug. If the directory depth is 2, why would you go up to level 3?

Ben on Jan 31, 2010:

I thing this is excellent! Thanks for saving me a headache. Now if I could just get back the last hour or so looking for this. *sigh* Such is the life of the coder. Thanks! Ben

chesser on Feb 8, 2010:

> I won't call it a bug. If the directory depth is 2, why would you go up to level 3?

I think it is a bug, look at the following link:
http://www.w3.org/2004/04/uri-rel-test.html - there are some tests for your function

Asri on May 5, 2010:

If I might suggest these instead of the last line of that function:

...
...
$result = $scheme.'://'.$abs;
return str_ireplace("../", "", $result);
}

Leave a comment

Name (required)
Email (will not be published) (required)
Website

Characters left = 1000

Tags

Recent Posts

  1. OpenCV Utility: Reading Image Pixels Value
  2. OpenCV Circular ROI
  3. OpenCV 2.0 Installation on Windows XP and Visual Studio 2008
  4. Runtime ROI Selection using Mouse
  5. Real Time Eye Tracking and Blink Detection
View Archives

About the Author

avatar Cool PHP programmer writing cool PHP scripts. Feel free to contact
Tel. +62 31 8662872
+62 856 338 6017
ICQ 489571630
Skype dede_bl4ckheart
Yahoo dede_bl4ckheart
Google nashruddin.amin

Recommended Sites:

Hacker's HTTP Client
HTML and CSS Tutorials
Stop Dreaming Start Action
Online Quran and Translation