6

I'm currently working on a PHP project and am looking for a way to get the URL for the root of the website; I have a configuration file at the root so I'm thinking as to using that to figure out the "base URL." I'm looking for a way to do it dynamically so I can locate the URL of the root of the website, i.e. http://domain.com/my_app/. I am doing my best to avoid using relative paths and am using PHP to generate the URLs for whatever I am using. For example, I am using PHP to generate CSS code and the CSS code link to images so I would like to get an absolute URL in here instead of a relative path.

my_app/
    admin/
        resources/
            css/
                admin-css.php
            imgs/
                login.png
    resources/
        css/
            css.php
        imgs/
            my-image.png
            shared-image.png
    config.php

In my resources/css/css.php file, I am looking at getting the "base URL" so I can generate an absolute URL to the imgs folder like http://domain.com/resources/imgs/my-image.png but currently I am getting http://domain.com/resources/css/imgs/my-image.png since the defines below look at getting the directory of the loaded PHP file, not the included one. I would also like to share images between the folders (i.e. access the shared-image.png file from the admin folder) so getting the base URL would be ideal in generating links. The reason I an avoiding relative paths is because I have a function that creates a URL, createURL(), so I can get all the URLs working without having to hard code anything.

<?php
DEFINE('HTTP_TYPE', $_SERVER['HTTP_X_FORWARDED_PROTO']);
DEFINE('HTTP_ROOT', $_SERVER['HTTP_HOST']);
DEFINE('HTTP_FOLDER', dirname($_SERVER['PHP_SELF']) . '/');
DEFINE('BASE_URL', HTTP_TYPE . "://" . HTTP_ROOT . HTTP_FOLDER);

function createURL($pathFromRoot)
{
    return BASE_URL . $pathFromRoot;
}

All of these defines are located in my configuration file, so I am thinking that the best way to do this is to get the URL for the config file (http://domain.com/my_app/config.php) and just strip the "config.php." Keep in mind, the website could be hosted deeper in a folder structure http://domain.com/my_app/another/folder/config.php or no sub folders http://domain.com/config.php.

Is this possible, if so how can it be done? Or is there another approach I should follow?

allejo
  • 2,076
  • 4
  • 25
  • 40
  • The URL on the client side, or the path on the server side? (Also note that `HTTP_X_FORWARDED_PROTO` is only set if the client sent the `X-Forwarded-Proto` header, which is not always the case.) – zneak Nov 01 '13 at 05:21
  • Not clear, you are in `resources/css` and expect to get `my_app/` or you are in my app, including a file in `resources/css` and getting this? – lampwins Nov 01 '13 at 05:24
  • Can't you just parse the part of the URL you want? You take your current BASE_URL and just split where it's wrong? – Michael Villeneuve Nov 01 '13 at 05:26
  • @zneak the client side URL @lampwins I'm in the `resources/css` directory and would like to get `my_app/`, I've edited my question. @MichaelVilleneuve the thing is I don't necessarily know what part would be wrong, I don't want to hard code anything – allejo Nov 01 '13 at 05:27
  • @allejo You don't know what's not good, but do you know what part is good? If so I got your answer – Michael Villeneuve Nov 01 '13 at 05:28
  • Have you considered ?.. Use this in your html and then simply use relative path everywhere else... – Roy M J Nov 01 '13 at 05:29
  • @MichaelVilleneuve the only thing that I know is good is the `http://domain.com/` but the `my_app` could exist or not or the website could be in year another folder like `my_app/test` – allejo Nov 01 '13 at 05:30
  • @RoyMJ I've been trying to avoid using relative paths – allejo Nov 01 '13 at 05:35
  • @allejo Sorry man, it's too late my brain is just not functionnal anymore (2 a.m.) I'll try to get back to you tomorrow if you still have no answer. Shouldn't be too hard to figure out. Tell me, why do you need such thing? Could you take some time to make your question a little bit more explicit adding one or two example and telling us why you need this? – Michael Villeneuve Nov 01 '13 at 05:48
  • @MichaelVilleneuve I edited my question in hopes of clearing things up, thank you very much – allejo Nov 01 '13 at 07:23

2 Answers2

6

After doing a var_dump of $_SERVER and messing around I found that I could generate the base URL with this solution, in case anyone stumbles upon this question. I'm sure there are other ways but this is what worked for me.

<?php
DEFINE('BASE_URL', HTTP_TYPE . "://" . HTTP_ROOT . substr(__DIR__, strlen($_SERVER[ 'DOCUMENT_ROOT' ])) . '/');
allejo
  • 2,076
  • 4
  • 25
  • 40
2

I just needed the same thing I combined the answers from here and here to create this solution which can be easily converted to multiple constants and/or a function. I use a single entry point for my web application (index.php) and have my config in a sub-folder. You can either strip the known folder as shown in the commented line of code or run this from the main folder. As example your structure could be either/or of:

  • /public/html/some/random/folders/THEAPP/config.php
    • $urlDir = str_replace($docRoot, '', $dirRoot);

or

  • /public/html/some/random/folders/THEAPP/include/config.php
    • $urlDir = str_replace('/include', '/',str_replace($docRoot, '', $dirRoot));

Entire Code:

$domain = $_SERVER['HTTP_HOST'];
$docRoot = $_SERVER['DOCUMENT_ROOT'];
$dirRoot = dirname(__FILE__);
$protocol = isset($_SERVER["HTTPS"]) ? 'https://' : 'http://';
//$urlDir = str_replace('/include', '/',str_replace($docRoot, '', $dirRoot));
$urlDir = str_replace($docRoot, '', $dirRoot);
$site_path = $protocol.$domain.$urlDir;
define ('BASE_URL', $site_path);

Based server configurations: The output may not contain a trailing slash / if wanted then use either of:

  • $urlDir = str_replace('/include', '/',str_replace($docRoot, '/', $dirRoot));
  • $urlDir = str_replace($docRoot, '/', $dirRoot);

BTW, the function seems unnecessary as example:

function createURL($pathFromRoot)
{
    return BASE_URL . $pathFromRoot;
}

//Anywhere you can call `createURL($value)` makes the following true
$isTrue = createURL('/static/js/my.js') === BASE_URL.'/static/js/my.js';
$someNeededURL = '/static/whatever/is/converted/';
$alsoTrue = createURL($someNeededURL) === BASE_URL.$someNeededURL;
//and just for fun
if ($isTrue.$alsoTrue === 11){
    echo 'Not eleven';
    } else {
        echo $isTrue.$alsoTrue.'!==11';
    };
Community
  • 1
  • 1
CrandellWS
  • 2,708
  • 5
  • 49
  • 111