38

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
  • 609
  • 2
  • 8
  • 15
  • 3
    Look at [parse_url()](http://php.net/manual/en/function.parse-url.php) – John Conde Aug 13 '13 at 23:35
  • 1
    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

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

If you're interested in the current script's scheme and host. Depending on web server configuration (reverse proxy, rewrites), what is "current" may not be what you see in the browser, but it is what PHP thinks it is dealing with.

Otherwise, if you have a URL at hand you want the root of, 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 substr() on the full URL, with the start of the "path" as the stop position, e.g.

$url = 'http://user:pass@localhost:80/some/folder/containing/something/here/or/there';

$parsedUrl = parse_url($url);
$root = substr($url, 0, strpos($url, $parsedUrl['path'], strlen($parsedUrl['scheme'] . '://'))) . '/';//gives 'http://user:pass@localhost:80/'

Note: The offset in strpos() is used to handle the case where the URL might already be the root.

boen_robot
  • 1,450
  • 12
  • 24
  • 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
  • 1
    @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
16

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,633
  • 15
  • 64
  • 91
14

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
  • 181
  • 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
4

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,279
  • 5
  • 24
  • 37