64

My site is on http://drupal8.local/. How do I get the drupal8.local part of that URL?

Url::fromRoute('<'current'>') or base_path() returns the path parth of the URL; For example, for http://drupal8.local/a/b/c/d/e/f, they return '/a/b/c/d/e/f' when I just need to get 'drupal8.local'.

How can I get that part of the URL?

1
  • 2
    Do you actually mean hostname or base URL? The base URL can include path portions when Drupal isn't run in the root directory. Commented Jun 1, 2016 at 15:25

7 Answers 7

118

You can get the hostname, "drupal8.local", directly from the getHost() request:

$host = \Drupal::request()->getHost(); 

In some cases you might want to get the schema as well, fx https://drupal8.local:

$host = \Drupal::request()->getSchemeAndHttpHost(); 
10
  • 39
    Note: \Drupal::request()->getSchemeAndHttpHost() will return http://drupal8.local. Commented Nov 22, 2016 at 14:54
  • 20
    Note if your site is on a subpath (e.g. your homepage is on drupal8.local/uk), this will not return the subpath. To do this you can use Url::fromRoute('<front>', [], ['absolute' => TRUE]); Commented Oct 5, 2017 at 12:42
  • 3
    Upvoting comments from leon.nk. Url is going to get you the sub directory and any port if you are on a non-standard port. And, Url is replaced by urlGenerator. Updated code is: \Drupal::urlGenerator()->generateFromRoute('<front>', [], ['absolute' => TRUE]); Commented May 9, 2018 at 16:02
  • 2
    Running this from Drush (version 8) this will give a result : Default. Commented May 28, 2018 at 12:07
  • 1
    Correct @Justme - drush is a command line tool so naturally there’s no http host Commented May 28, 2018 at 13:14
10

There are some warnings about directly accessing the request object in this way in \Drupal::request:

 * Note: The use of this wrapper in particular is especially discouraged. Most * code should not need to access the request directly. Doing so means it * will only function when handling an HTTP request, and will require special * modification or wrapping when run from a command line tool, from certain * queue processors, or from automated tests. * * If code must access the request, it is considerably better to register * an object with the Service Container and give it a setRequest() method * that is configured to run when the service is created. That way, the * correct request object can always be provided by the container and the * service can still be unit tested. 

Any form controller extending \Drupal\Core\Form\FormBase automatically has this dependency injected, and it may be accessed using:

$this->getRequest()->getSchemeAndHttpHost() 

I think (but haven't tested) that a regular page controller extending \Drupal\Core\Controller\ControllerBase could provide the request_stack service by overriding the \Drupal\Core\Controller\ControllerBase::create function, and then setting a $request property in the constructor. This is described really well for forms, and the same process should apply for page controllers: https://www.drupal.org/docs/8/api/services-and-dependency-injection/dependency-injection-for-a-form.

10

If you'd like to do this with dependency injection and a service, then you can use RequestStack:

use Symfony\Component\HttpFoundation\RequestStack; 

And define it like this:

protected $request; public function __construct(..., RequestStack $request_stack) { ... $this->request = $request_stack->getCurrentRequest(); } public static function create(ContainerInterface $container, ...) { return new static( ... $container->get('request_stack') ) } 

And then declare it like this:

$this->request->getHost() $this->request->getSchemeAndHttpHost() 
9

Taking into account the "warnings about directly accessing the request object in this way in \Drupal::request" that Shaun Dychko mentioned, perhaps a good option to get the hostname is obtain it from the $base_url global variable, with the help of php function parse_url:

global $base_url; $base_url_parts = parse_url($base_url); $host = $base_url_parts['host']; 
6

Code below is how core defines the [site:url] token. This works best in all cases for me in drupal 8 & 9:

$url_options = [ 'absolute' => TRUE, 'language' => \Drupal::languageManager()->getCurrentLanguage(), ]; $site_url = Url::fromRoute('<front>', [], $url_options)->toString(); 
1
  • This adds language prefix if present, like 'drupal8.local/en/' Commented Sep 28, 2021 at 9:38
1
<?php $url = \Drupal\Core\Url::fromUserInput('/', ['absolute' => TRUE])->toString(); ?> 
-1
\Drupal::request()->getBaseUrl() 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.