如何在Symfony2控制器中获取用户IP地址?


72

提交表单后,我需要在数据库中存储评论用户的IP地址。

是否有任何symfony2函数来获取IP?还是通过其他方式获取IP?

Answers:


150

您可以使用请求服务获取客户端IP:

$container->get('request')->getClientIp();

感谢您及时的回复。我可以知道$ container来自何处。
VishwaKumar 2012年

15
好的,它是这样工作的:$ ip = $ this-> container-> get('request')-> getClientIp();
VishwaKumar 2012年

2
请注意,最佳做法是$request直接使用注射剂,而不是从容器中取出,因此只需使用$request->getClientIp()就足够了
Rein Baarsma

50

在Symfony 2.3中, $this->container->get('request')->getClientIp()仅在主请求控制器内部起作用。在子请求控制器中,它总是返回127.0.0.1。如果您的项目在Symfony 2.2中使用了子请求,那么防弹解决方案是创建kernel.request侦听器并将主请求中的IP保存在其中。

在Symfony 2.3中,此问题已修复,因此对于内部子请求,将真实IP推送到代理列表,请参见https://github.com/symfony/symfony/commit/2f3b33a630727cbc9cf21262817240a72a8dae0c, 因此您需要添加127.0.0.1trusted_proxies配置参数中以获取客户端ip从Symfony 2.3+的子请求中的Request中获取IP,但是出于安全原因,您不应该在共享主机上执行此操作。

此外,如果在Symfony 2.3.20之前使用了内置的HTTP缓存(in ),则127.0.0.1必须trusted_proxies显式添加。该缓存试图看起来像一个真正的反向代理,并修改了主请求的某些标头。已在https://github.com/symfony/symfony/commit/902efb8a84e8f0acf6a63e09afa08e3dcdd80fb9中修复AppCacheweb/app.php

从Symfony 2.43.x开始,访问当前请求的首选方法是使用request_stackservice

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

或将请求注入控制器,请参见http://symfony.com/doc/current/book/controller.html#the-request-as-a-controller-argument

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

但是,在子请求中使用127.0.0.1时仍需排除的问题仍然存在,但是现在您可以尝试使用

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

我正在使用Symfony 2.3.11,但是我的子请求仍然返回127.0.0.1(我们不使用内置缓存),因此在我看来它仍未修复。
新韩2014年

@Shinhan我研究了相关代码,发现他们接受了另一种方法。现在,内部子请求应与内部HTTP缓存相同。我已经更新了答案,但尚未测试解决方案。
Konstantin Pelepelin 2014年

还有一个始终信任127.0.0.1的公开请求:github.com/symfony/symfony/issues/9292
Konstantin Pelepelin 2014年

我得到的是10.0.2.2,我认为那不是我的IP。我正在本地计算机上进行测试,也许我应该在线进行测试?
Joe Yahchouchi 2015年

@JoeYahchouchi这是在本地或虚拟网络中完全有效的IP,但是如果您在真实的网站上获得此IP,则应向您的托管服务提供商咨询其反向代理设置。
Konstantin Pelepelin

18

仅供参考,从Symfony 2.0版开始 Request::getClientIp$proxy 参数弃用。它将在Symfony 2.3中删除

您可以使用

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

或作为@meze答案

$container->get('request')->getClientIp();

不赞成使用getClientIp的“代理”参数。github.com/symfony/symfony/compare/922c201...e5536f0.patch
Riccardo Galli

2
我从不推荐使用REMOTE_ADDR。它可能在您的开发机器上本地工作,但是如果您的生产应用程序前面有任何反向代理或负载平衡器,您的代码就会中断。getClientIp()是在Symfony中获取客户端IP的唯一可信赖的方法。
贾里德·马克尔

7

对于Symfony 2.6+,请使用以下代码(在您的控制器内:

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

1

还有另一种将当前客户端IP注入任何服务或方法调用的方法:

acme.currentIP:
    class: some\service\className
    arguments:
        - "@=service('request_stack').getCurrentRequest().getClientIp()"

3
这是一个不好的方法。更好地将请求堆栈自身注入并在构造函数中获取IP

@ Sharpy35没有理由避免这种方法,我怀疑客户端的IP在请求期间发生变化吗?
Volker

我看不到这种方法如何工作。构建服务(和缓存)请求到来之前
赖因Baarsma

没有,此代码描述服务将如何被构建,所以这就是所谓的请求到达后
沃尔克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.