76

I need to store the IP address of the users who comment, in the database after form submission.

Is there any symfony2 function to get the IP? Or any other way to get the IP?

j0k
  • 22,600
  • 28
  • 79
  • 90
VishwaKumar
  • 3,433
  • 8
  • 44
  • 72

5 Answers5

156

You can get the client IP using Request service:

$container->get('request')->getClientIp();
apaderno
  • 28,547
  • 16
  • 75
  • 90
meze
  • 14,975
  • 4
  • 47
  • 52
54

In Symfony before 2.3 $this->container->get('request')->getClientIp() works only inside of master request controller. In sub-request controller this always returns 127.0.0.1. In case your project uses sub-requests with Symfony 2.2, the bullet-proof solution is to create kernel.request listener and save the IP from the master request in it.

In Symfony 2.3 this was fixed so for internal sub-requests the real IP is pushed to the list of proxies, see https://github.com/symfony/symfony/commit/2f3b33a630727cbc9cf21262817240a72a8dae0c So you need to add 127.0.0.1 to trusted_proxies configuration parameter to get client ip from the Request in sub-requests in Symfony 2.3+, but you shouldn't do this on shared hosting for security reasons.

Also, 127.0.0.1 had to be added to trusted_proxies explicitly if built-in HTTP cache (AppCache in web/app.php) was used before Symfony 2.3.20. This cache tries to look like a real reverse-proxy and modifies some headers of master request. Fixed in https://github.com/symfony/symfony/commit/902efb8a84e8f0acf6a63e09afa08e3dcdd80fb9

Since Symfony 2.4 and in 3.x the preferred way to access current request is either using request_stack service

$this->container->get('request_stack')->getCurrentRequest()->getClientIp();

or injecting Request into controller, see http://symfony.com/doc/current/book/controller.html#the-request-as-a-controller-argument

public function indexAction(Request $request)
{
    $ip = $request->getClientIp();
}

But the concern about excluding 127.0.0.1 when used in sub-requests still apply, but now you may try to explicitly refer to master request using

$this->container->get('request_stack')->getMasterRequest()->getClientIp();
Konstantin Pelepelin
  • 1,303
  • 1
  • 14
  • 29
  • I'm using Symfony 2.3.11 but my subrequests still return 127.0.0.1 (we're nto using built-in caching), so it looks to me like its still not fixed. – Shinhan Mar 25 '14 at 09:30
  • @Shinhan I've looked into related code and found they've accepted another approach. Now internal sub-requests should work the same way as the internal HTTP cache. I've updated the answer, but I have not tested the solution. – Konstantin Pelepelin Apr 03 '14 at 21:24
  • There is also an open request to always trust 127.0.0.1: https://github.com/symfony/symfony/issues/9292 – Konstantin Pelepelin Apr 03 '14 at 21:31
  • I am getting 10.0.2.2 I do not think that is really my ip. I am testing on a local machine though, maybe I should test online? – Joe Yahchouchi Jan 20 '15 at 08:25
  • @JoeYahchouchi It's a perfectly valid IP in a local or virual network, but if you get this on a real web site, you should consult with your hosting provider about their reverse proxy setup. – Konstantin Pelepelin Jan 22 '15 at 18:03
  • Yes that is correct. Virtual box reads my real machine that way. When I tested online it returned a good result. – Joe Yahchouchi Jan 23 '15 at 08:47
  • $request->getClientIp() still works great as of Symfony 4.1.x – Robert Saylor Nov 12 '18 at 12:41
18

FYI, As of Symfony 2.0 Request::getClientIp the $proxy parameter is deprecated. It will be removed in Symfony 2.3.

You can either use

$container->get('request')->server->get("REMOTE_ADDR");

or as @meze answer

$container->get('request')->getClientIp();
yvoyer
  • 7,476
  • 5
  • 33
  • 37
  • 1
    Only the "proxy" argument to getClientIp has been deprecated. https://github.com/symfony/symfony/compare/922c201...e5536f0.patch – Riccardo Galli Mar 04 '13 at 10:34
  • 2
    I never recommend the usage of REMOTE_ADDR. It may work locally on your dev machine, but if your production application has any sort of reverse proxy or load balancer in front of it, your code will break. getClientIp() is the only trustable way to get your client's IP in Symfony. – jmar Aug 19 '14 at 18:20
7

For Symfony 2.6+ use the following code (within your controller:

      $this->container->get('request_stack')->getCurrentRequest()->getClientIp();
shacharsol
  • 2,326
  • 20
  • 14
1

there is also another way to inject the current client IP into any service or method call:

acme.currentIP:
    class: some\service\className
    arguments:
        - "@=service('request_stack').getCurrentRequest().getClientIp()"
Volker
  • 611
  • 1
  • 7
  • 21
  • 3
    this is a bad approach. better inject the request stack it self and grab the ip in the constructor –  Nov 18 '16 at 09:49
  • @Sharpy35 there is no reason to avoid this approach, i doubt that the IP of the client changes during the request? – Volker Jul 10 '18 at 09:39
  • I don't see how this approach works. The services are constructed (and cached) before a request comes in. – Rein Baarsma Jul 07 '20 at 07:07
  • no, this code describe how the service will be construct, so this is called after a request comes in. – Volker Dec 08 '20 at 08:48