views:

591

answers:

4

I'm developing a PHP website that uses url routing. I'd like the site to be directory independent, so that it could be moved from http://site.example.com/ to http://example.com/site/ without having to change every path in the HTML. The problem comes up when I'm linking to files which are not subject to routing, like css files, images and so on.

For example, let's assume that the view for the action index of the controller welcome contains the image img/banner.jpg. If the page is requested with the url http://site.example.com/welcome, the browser will request the image as http://site.example.com/img/banner.jpg, which is perfectly fine. But if the page is requested with the url http://site.example.com/welcome/index, the browser will think that welcome is a directory and will try to fetch the image as http://site.example.com/welcome/img/banner.jpg, which is obviously wrong.

I've already considered some options, but they all seem imperfect to me:

  • Use url rewriting to redirect requests from (*.css|*.js|...) or (css/*|js/*|...) to the right path.

    Problems: Every extension would have to be named in the rewrite rules. If someone would add a new filetype (e.g. an mp3 file), it wouldn't be rewritten.

  • Prepend the base path to each relative path with a php function. For example:
    <img src="<?php echo url::base(); ?>img/banner.jpg" />

    Problems: Looks messy; css- and js-files containing paths would have to be processed by PHP.

So, how do you keep a website directory independent? Is there a better/cleaner way than the ones I came up with?

+7  A: 

You could put in the head

<base href="<?php echo url::base(); ?>" />

This will mean the browser will request any non-absolute URLs relative to that path. However I am not sure how this would affect URLs embedded in CSS files etc. This does not affect paths defined in CSS files. (thanks mooware)

Tom Haigh
According to the CSS specification, URLs in CSS files are resolved relative to the path of the file they are defined in. So the base-tag doesn't affect them at all. I tried it, and it really works that way.
mooware
+1  A: 

tomhaigh has a good point, and would be worthwhile to investigate it further.

According to MSDN, the base tag works for all external sources, including style sheets, images, etc.

Anton Babushkin
A: 

Perhaps I'm missing something, but can't you just do what I (and I thought everybody else) do/es? Namely put all your images, css, javascripts, etc in a common directory i.e.:

/inc/images/
/inc/css/
/inc/javascript/
etc

And then reference them with base-relative URLs, i.e.:

<img src="/inc/images/foo.jpg" />
etc

?

da5id
+1  A: 

The <base> thing will work but you need to remember it's going to affect your <a> tags too. Consider this example.:

<!-- this page is http://oursite.com/index.html -->
<html>
 <head>
    <base href="http://static.oursite.com/" />
 </head>
 <body>
    <img src="logo.gif" alt="this is http://static.oursite.com/logo.gif" />
    <a href="/login">this links to http://static.oursite.com/login which is not what we wanted.  we wanted http://oursite.com/login&lt;/a&gt;
 </body>
</html>

If you use a PHP function call for creating your links, that won't be a problem as you can just make sure it spits out absolute URL. But if you (or your designers) hand-code the <a> tags then you're stuck with the same problem again, just now with <a> instead of <img>.

EDIT: I should add the above paragraph is assuming you serve images from a different host name like we do. If you don't then obviously that won't be a problem.