105

I'm making the switch from CodeIgniter to Symfony 2. Can someone please give me an example of how to:

  • Get the base url (the url without the route specific parts)
  • Globally pass this variable to the twig bundle so I can use it in every template.
Mohammed H
  • 6,880
  • 16
  • 81
  • 127
Geoffrey De Vylder
  • 3,963
  • 7
  • 36
  • 56
  • possible duplicate of [Dynamically setting the BaseUrl within configuration in Symfony2](http://stackoverflow.com/questions/6381809/dynamically-setting-the-baseurl-within-configuration-in-symfony2) – Dan Grossman Jul 27 '11 at 07:06

14 Answers14

157

This is now available for free in twig templates (tested on sf2 version 2.0.14)

{{ app.request.getBaseURL() }}

In later Symfony versions (tested on 2.5), try :

{{ app.request.getSchemeAndHttpHost() }}
codecowboy
  • 9,835
  • 18
  • 79
  • 134
  • 38
    This can even be shortened to `{{ app.request.baseUrl }}` (it will locate the getter method and call that automatically) – Colin O'Dell Feb 05 '13 at 20:32
  • 3
    @Colin O'Dell furthermore, it's even more appriopriate NOT TO USE the method calls in view - the view should not know what methods are in the object. Although it looks slightly diffrent in symfony, but +10 for that answer anyway. – thorinkor May 21 '13 at 08:24
  • 2
    If I am not using *twig* then how can I rewrite this in *PHP* ? – Nis Jun 24 '14 at 03:22
  • 6
    This does NOT work in later versions (tested on sf 2.5). The below answer `{{ app.request.getSchemeAndHttpHost() }}` works! – RayOnAir Jan 13 '15 at 16:13
97

Why do you need to get this root url ? Can't you generate directly absolute URL's ?

{{ url('_demo_hello', { 'name': 'Thomas' }) }}

This Twig code will generate the full http:// url to the _demo_hello route.

In fact, getting the base url of the website is only getting the full url of the homepage route :

{{ url('homepage') }}

(homepage, or whatever you call it in your routing file).

Damien
  • 5,872
  • 2
  • 29
  • 35
  • Thanks a lot, I thought this was the way to go but I only knew about the {{ path(..) }} function, leading to wrong results. {{ url }} is just what I needed. – Geoffrey De Vylder Jul 28 '11 at 06:56
  • what in case I am rendering the twig from symfony console command, lets say to generate email template, I need base URL. How do I do in that case. – vishal Jul 26 '13 at 05:51
  • 1
    There is a cookbook for that: http://symfony.com/doc/master/cookbook/console/sending_emails.html – Damien Jul 29 '13 at 07:51
  • If I am not using *twig* then how can I rewrite this in *PHP* ? – Nis Jun 24 '14 at 03:23
  • This does not answer the question. – Cyril CHAPON Oct 19 '16 at 15:01
  • 1
    Not workingFatal error: Uncaught Twig_Error_Syntax: Unknown "url" function in "default/template/extension/module/featured.twig" at line 5. in J:\xampp\htdocs\sites\opencart3020\system\library\template\Twig\ExpressionParser.php:574 Stack trace: #0 – Kamlesh Mar 02 '19 at 13:22
  • Even if this is not answering the exact question asked, it did help the asker at the time and even me right now (using Symfony 5/6). Thanks for the help so I didn't complicate things more than necessary! ^^ For reference, here is the doc for the `url()` function: https://symfony.com/doc/current/reference/twig_reference.html#url – Alexander Jordan Nov 24 '22 at 09:00
59

You can use the new request method getSchemeAndHttpHost():

{{ app.request.getSchemeAndHttpHost() }}
Hugo Nogueira
  • 1,298
  • 1
  • 12
  • 24
51

Valid from Symfony v2.1 through v6.0+

If you want the base URL to a Symfony application, you should use getSchemeAndHttpHost() concatenated together with getBaseUrl(), similar to how getUri() works, except without the router path and query string.

{{ app.request.schemeAndHttpHost ~ app.request.baseUrl }}

For example, if your Symfony website URL lives at https://www.stackoverflow.com/webapp/, then these two methods return these values:

getSchemeAndHttpHost

https://www.stackoverflow.com

getBaseUrl

/webapp

Note: getBaseUrl() includes the script filename (ie /app.php) if it's in your URL.

Matt Janssen
  • 1,505
  • 13
  • 14
  • 2
    And still valid with 5.4 (probably 6 too, but I don't have anything to test that on right now). This should be the top answer. – Andrew Dinmore Mar 17 '22 at 17:12
  • 1
    There is a scenario which this doesn't work as expected. That is cloud deployment in Azure for example where SSL is terminated at the load balancer. Thus scheme will be http instead of https. – AQuirky Sep 15 '22 at 23:38
37

Base url is defined inside Symfony\Component\Routing\RequestContext.

It can be fetched from controller like this:

$this->container->get('router')->getContext()->getBaseUrl()
sumanchalki
  • 1,457
  • 17
  • 21
20

For Symfony 2.3+, to get the base url in a controller should be

$this->get('request')->getSchemeAndHttpHost();
Mr. 14
  • 9,228
  • 6
  • 37
  • 54
16
 <base href="{{ app.request.getSchemeAndHttpHost() }}"/>

or from controller

$this->container->get('router')->getContext()->getSchemeAndHttpHost()
user3869574
  • 179
  • 1
  • 2
5

Also for js/css/image urls there's handy function asset()

<img src="{{ asset('image/logo.png') }}"/>

This creates an absolute url starting with /.

commonpike
  • 10,499
  • 4
  • 65
  • 58
Sash
  • 315
  • 3
  • 6
  • 3
    Please add some more explanation to your answer - does asset use the baseUrl after all? In my projects, it just prints a relative URL – Nico Haase Dec 13 '19 at 13:12
  • in my project, asset uses the baseurl, but not host and scheme. it makes an absolute url starting with /. so it works fine as ` – commonpike Jan 30 '21 at 18:10
4

For current Symfony version (as of writing this answer it's Symfony 4.1) do not directly access the service container as done in some of the other answers.

Instead (unless you don't use the standard services configuration), inject the request object by type-hinting.

<?php

namespace App\Service;

use Symfony\Component\HttpFoundation\RequestStack;

/**
 * The YourService class provides a method for retrieving the base URL.
 *
 * @package App\Service
 */
class YourService
{

    /**
     * @var string
     */
    protected $baseUrl;

    /**
     * YourService constructor.
     *
     * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
     */
    public function __construct(RequestStack $requestStack)
    {
        $this->baseUrl = $requestStack->getCurrentRequest()->getSchemeAndHttpHost();
    }

    /**
     * Returns the current base URL.
     *
     * @return string
     */
    public function getBaseUrl(): string
    {
        return $this->baseUrl;
    }
}

See also official Symfony docs about how to retrieve the current request object.

Arvid
  • 1,021
  • 2
  • 17
  • 25
2

In Symfony 5 and in the common situation of a controller method use the injected Request object:

public function controllerFunction(Request $request, LoggerInterface $logger)
  ...
  $scheme = $request->getSchemeAndHttpHost();
  $logger->info('Domain is: ' . $scheme);
  ...
  //prepare to render
  $retarray = array(
    ...
    'scheme' => $scheme,
    ...
    );
  return $this->render('Template.html.twig', $retarray);
}
Vladtn
  • 2,506
  • 3
  • 27
  • 23
2

Instead of passing variable to template globally, you can define a base template and render the 'global part' in it. The base template can be inherited.

Example of rendering template From the symfony Documentation:

<div id="sidebar">
  {% render "AcmeArticleBundle:Article:recentArticles" with {'max': 3} %}
</div>
cheesemacfly
  • 11,622
  • 11
  • 53
  • 72
Sethunath K M
  • 4,702
  • 3
  • 28
  • 42
0
{{ dump(app.request.server.get('DOCUMENT_ROOT')) }}
Ivan Proskuryakov
  • 1,625
  • 2
  • 23
  • 32
0

In one situation involving a multi-domain application, app.request.getHttpHost helped me out. It returns something like example.com or subdomain.example.com (or example.com:8000 when the port is not standard). This was in Symfony 3.4.

ACJ
  • 2,499
  • 3
  • 24
  • 27
-3

I tried all the options here but they didnt work for me. Eventually I got it working using

{{ site.url }}

Hope this helps someone who is still struggling.