Baumr
Baumr

Reputation: 6284

How to implement absolute URLs on localhost and web server?

I've typically used the following linking practice, of relative URLs with an absolute URL path:

<a href="/relative/path/to/document.html">

But I will implement absolute URLs:

<a href="http://example.com/relative/path/to/document.html">

It's not a problem for me to change them (automated find & replace in HTML documents).

But what is the best practice to make sure that it will work on both my localhost (which supports PHP), as well as on the web? And why?


For example, here's how I do PHP includes:

<?php include($_SERVER['DOCUMENT_ROOT']."/relative/path/to/document.html"); ?>

Adopt the same approach for href URLs? Is a different PHP technique better? Curious to hear why.

Upvotes: 5

Views: 17109

Answers (5)

Dmitry Gamolin
Dmitry Gamolin

Reputation: 1006

Here is a solution that works both on remote and local servers and doesn't require to change the domain name:

$protocol = isset($_SERVER["HTTPS"]) ? 'https://' : 'http://';
$url_base = $protocol . $_SERVER['HTTP_HOST'];

With these 2 lines you won't need to change the code if you change your domain name and also you won't need to change it if you switch between HTTP and HTTPS. Feel free to change variable names as you prefer.

So then your code for links would look something like this:

<a href="<?php echo $url_base; ?>/relative/path/to/document.html">link</a>

IMPORTANT UPDATE REGARDING SECURITY:

There is however a security risk with this solution. Here's an article on it.

The $_SERVER['HTTP_HOST'] and $_SERVER['SERVER_NAME'] variables can be changed by sending a different Host header when accessing the site:

curl -H "Host: notyourdomain.com" http://yoursite.com/

Doing that, any URLs that used $_SERVER['HTTP_HOST'] or $_SERVER['SERVER_NAME'] would use notyourdomain.com.

Taking this further, imagine an attacker fills out a password reset form with your email and changes the Host header. The password reset email would then direct you to their site. If you’re paying attention to the domain, you’re fine, but normal users don’t and that’s why phishing attacks work.

So use it with caution or better avoid using it.

Here's a way to deal with multiple environments from the linked article:

When dealing with multiple environments, you can use $_SERVER['HTTP_HOST'] and $_SERVER['SERVER_NAME'], but only to check which domain you’re on and then manually set the correct URL. You could keep it simple with an array of valid domains:

$domains = array('domain.com', 'dev.domain.com', 'staging.domain.com', 'localhost');
if (in_array($_SERVER['HTTP_HOST'], $domains)) {
    $domain = $_SERVER['HTTP_HOST'];
}else {
    $domain = 'localhost';
}

You can also make it a bit shorter:

$domains = array('domain.com', 'dev.domain.com', 'staging.domain.com', 'localhost');
$domain = in_array($_SERVER['HTTP_HOST'], $domains) ? $_SERVER['HTTP_HOST'] : 'localhost';

Upvotes: 1

Jain Shubham
Jain Shubham

Reputation: 3

Instead of doing this, you can add below line to your head tag. Now you can give all urls relative to your root. Now, when you upload to server or work on localhost. Just change url here.

<base href="http://mydomin.com/" />

Upvotes: 0

rink.attendant.6
rink.attendant.6

Reputation: 46257

Keep the same directory structure locally and on the web host, and use relative URIs and paths whenever possible. If you must use an absolute URI, define it once somewhere and use the constant whenever you need to output a URI to avoid having to make the changes using find and replace.

<?php
    define('ROOT_URI', 'http://example.com/subdirectory');
?>

<a href='<?php echo ROOT_URI; ?>/relative/path/to/document.html'> document </a>

It's easier if you have a configuration file or some other included file where you only define it once.

Upvotes: 6

ymmyk
ymmyk

Reputation: 101

That all depends on how you plan on hosting the content. PHP is not a bad choice as there are oodles of hosting companies that support PHP. Without a scripting language like PHP, your best bet would be javascript, but depending why you are trying to make the URL's absolute, that might defeat your purpose.

One thing I would suggest is making a configuration file as you may or may not be able to depend on $_SERVER['DOCUMENT_ROOT'].

Say: config.php

<?php
define("HOST", "http://example.com");
// Whatever else you might need on all files.

Then every file that needs it, put this at the top

<?php
include_once(dirname(__FILE__)."/config.php");

// Keep in mind this path is relative to current file, so if you are 3 sub-folder keep
// include_once(dirname(__FILE__)."/../../../config.php")
?>

...

<a href=<?php echo HOST;?>/relative/path/to/document.html">...

Upvotes: 3

hammus
hammus

Reputation: 2612

You could just include a predefined constant or variable in the HTML hrefs.

e.g.

<?php
define("LOCAL", "http://localhost");
define("WEB", "http://foo.bar");
$environment = LOCAL; //change to WEB if you're live
?>
<a href="<?php echo $environment; ?>/relative/path/to/document.html">

Upvotes: 6

Related Questions