34

Might be a trivial question, but I am looking for a way to say get the root of a site url, for example: http://localhost/some/folder/containing/something/here/or/there should return http://localhost/

I know there is $_SERVER['DOCUMENT_ROOT'] but that's not what I want.

I am sure this is easy, but I have been reading: This post trying to figure out what i should use or call.

Ideas?

The other question I have, which is in relation to this one is - will what ever the answer be, work on sites like http://subsite.localhost/some/folder/containing/something/here/or/there so my end result is http://subsite.localhost/

Adam
  • 559
  • 2
  • 6
  • 14
  • 3
    Look at [parse_url()](http://php.net/manual/en/function.parse-url.php) – John Conde Aug 13 '13 at 23:35
  • if you have a single entry point for your site and/or you always include a config file you can use [this solution](http://stackoverflow.com/a/23864090/1815624). – CrandellWS May 26 '14 at 07:35

5 Answers5

57
$root = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . '/';

If you're interested in the current script's scheme and host.

Otherwise, parse_url(), as already suggested. e.g.

$parsedUrl = parse_url('http://localhost/some/folder/containing/something/here/or/there');
$root = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/';

If you're also interested in other URL components prior to the path (e.g. credentials), you could also use strstr() on the full URL, with the "path" as the needle, e.g.

$url = 'http://user:pass@localhost:80/some/folder/containing/something/here/or/there';
$parsedUrl = parse_url($url);
$root = strstr($url, $parsedUrl['path'], true) . '/';//gives 'http://user:pass@localhost:80/'
boen_robot
  • 1,463
  • 12
  • 22
  • I'm reading `parse_url()` and I am not understanding how I would set it up, to give me what I want. Any ideas? sorry. but thanks for your help. – Adam Aug 13 '13 at 23:39
  • 1
    @Adam I've altered the answer above with an example for parse_url(). It's simple really - it gives you an associative array with all URL components, and you pick those you want. In your case, scheme and host. – boen_robot Aug 13 '13 at 23:43
  • @boen_robot: good work, but don't leave out stuff like the username, portnumbers, etc. that may be in there, look [here for instance](https://github.com/akky/anti-hatena-bookmark/blob/master/http_build_url.php#L106) – Wrikken Aug 13 '13 at 23:54
  • @Wrikken Well, it didn't seem like Adam wants that in particular, but I guess for the sake of others reading... I've modified the answer above to also include an example that would cover the scenarios you're talking about. – boen_robot Aug 14 '13 at 00:05
  • That information makes sense, yet I have one last question, if i have sub domains, such as `bla.localhost/site/content/here` and I use the above answer - will I get `bla.localhost/` back? or will I get. – Adam Aug 14 '13 at 00:07
  • @Adam Yes, you'll get the subdomain too. The full hostname in fact. If you're interested in individual portions of the host, do explode('.', $parsedUrl['host']), and inspect the resulting array (where each member is from the deepest subdomain up to the TLD). – boen_robot Aug 14 '13 at 00:11
  • @boen_robot Sorry I meant with $`root = ... ` example – Adam Aug 14 '13 at 00:31
  • @Adam Right. In all examples above, the hostname will include subdomains too, so ```http://bla.localhost/site/content/here``` will give you ```http://bla.localhost/``` with all examples. – boen_robot Aug 14 '13 at 00:48
  • 1
    those who get the error `Undefined index: HTTPS` please do as in the following link [click me](http://stackoverflow.com/questions/17218926/how-to-get-rid-of-php-notice-undefined-index-https-in-x-on-line-123) – gvgvgvijayan Jun 27 '14 at 11:38
  • @gvgvgvijayan I hadn't tested that first piece of code, so thanks... I've corrected the code above to use "!empty($_SERVER['HTTPS'])", which AFAIK should remove this notice, since an isset() is implicitly done. – boen_robot Aug 18 '14 at 16:25
  • beware: the examples give you wrong paths with activated `php mod_rewrite` rules – escalator Mar 11 '15 at 10:46
17

Another simple way:

<?php
$hostname = getenv('HTTP_HOST');
echo $hostname;

getenv

(PHP 4, PHP 5)

getenv — Gets the value of an environment variable

daniel__
  • 11,255
  • 14
  • 61
  • 91
13

This PHP function returns the real URL of a full path.

function pathUrl($dir = __DIR__){

    $root = "";
    $dir = str_replace('\\', '/', realpath($dir));

    //HTTPS or HTTP
    $root .= !empty($_SERVER['HTTPS']) ? 'https' : 'http';

    //HOST
    $root .= '://' . $_SERVER['HTTP_HOST'];

    //ALIAS
    if(!empty($_SERVER['CONTEXT_PREFIX'])) {
        $root .= $_SERVER['CONTEXT_PREFIX'];
        $root .= substr($dir, strlen($_SERVER[ 'CONTEXT_DOCUMENT_ROOT' ]));
    } else {
        $root .= substr($dir, strlen($_SERVER[ 'DOCUMENT_ROOT' ]));
    }

    $root .= '/';

    return $root;
}

Call of pathUrl in this file : http://example.com/shop/index.php

#index.php

echo pathUrl();
//http://example.com/shop/

Work with alias : http://example.com/alias-name/shop/index.php

#index.php

echo pathUrl();
//http://example.com/alias-name/shop/

For sub directory : http://example.com/alias-name/shop/inc/config.php

#config.php

echo pathUrl(__DIR__ . '/../');
//http://example.com/alias-name/shop/
fallinov
  • 171
  • 1
  • 5
  • I removed your links to localhost, other people who are visiting the internet on different computers do not have access to your localhost box. Also your other link to /myweb.com/tests/ does not resolve. – Eric Leschinski Mar 19 '16 at 15:19
3

You can using Define save on define.php include for next time use on other project This is PROTOCOL DOMAIN PORT SITE_ROOT AND SITE PATH

**
 * domain
 * ex: localhost, maskphp.com, demo.maskphp.com,...
 */
define('DOMAIN', isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']);

/**
 * protocol
 * ex: http, https,...
 */
define('PROTOCOL', isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1)
    || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ? 'https' : 'http');

/**
 * port
 * ex: 80, 8080,...
 */
define('PORT', $_SERVER['SERVER_PORT']);

/**
 * site path
 * ex: http://localhost/maskphp/ -> /maskphp/
 */
define('SITE_PATH', preg_replace('/index.php$/i', '', $_SERVER['PHP_SELF']));

/**
 * site root
 * ex: http://maskgroup.com, http://localhost/maskphp/,...
 */
define('SITE_ROOT', PROTOCOL . '://' . DOMAIN . (PORT === '80' ? '' : ':' . PORT) . SITE_PATH);

You can debug to see result

Dinh Phong
  • 596
  • 3
  • 12
1

You can preg_split the URL at the first single /-character:

function rootUrl($url) {
  $urlParts = preg_split('#(?<!/)/(?!/)#', $url, 2);
  return $urlParts[0] != '' ? $urlParts[0] . '/' : '';
}

// examples:

echo rootUrl('http://user@www.example.com/path/to/file?query=string');
// output: http://user@www.example.com/

echo rootUrl('https://www.example.com/');
// output: https://www.example.com/

echo rootUrl('https://www.example.com');
// output: https://www.example.com/

echo rootUrl('example.com/path/to/file');
// output: example.com/

echo rootUrl('/path/to/file');
// output: [empty]

echo rootUrl('');
// output: [empty]

The function rootUrl($url) returns the part of the given string $url before the first /-character plus a trailing / if that first part is not empty. For URLs starting with a / (relative URLs) an empty string is returned.

x-ray
  • 3,139
  • 5
  • 22
  • 34