Php 登录后对字符串调用成员函数getId()

Php 登录后对字符串调用成员函数getId(),php,symfony,symfony3.x,Php,Symfony,Symfony3.x,我正在访问需要用户登录的站点部分。但是,系统没有先登录,然后再登录到我想要访问的站点,而是向我显示一个错误,指示我没有登录 控制器代码如下所示: /** * @Route("/estrategia/titulares", name="estrategia_titulares") */ public function estrategiaTitularesAction(Request $request) { $em = $this->getDoctrine()

我正在访问需要用户登录的站点部分。但是,系统没有先登录,然后再登录到我想要访问的站点,而是向我显示一个错误,指示我没有登录

控制器代码如下所示:

/**
* @Route("/estrategia/titulares", name="estrategia_titulares")
*/
    public function estrategiaTitularesAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $logged = $this->get('security.token_storage')->getToken()->getUser();
        $user = $em->getRepository('AppBundle:User')->find($logged->getId());

        if(!$user)
        {
            $messageException = $this->get('translator')->trans('No se ha encontrado el usuario');
            throw $this->createNotFoundException($messageException);
        }
出现的错误在
$user=$em->getRepository

对字符串调用成员函数getId()


如何才能使系统首先要求我登录,然后将我重定向到我要访问的页面?

由于您试图检测用户是否登录,因此完全有可能您根本没有获得用户实体

如果用户未登录,您将无法从令牌存储服务获取“用户对象”,并且您将在尝试访问其属性时收到错误

此外,您的用户已在该点从数据库中刷新(如果正确验证),因此从条令中获取它是多余的,您可以避免它

正确的方法是,假设您的用户类实现了
Symfony\Component\Security\Core\user\UserInterface

$user = $this->get('security.token_storage')->getToken()->getUser();

if (!$user instanceof UserInterface) {
    // failure mode. Throw exception, return RedirectResponse, or what you prefer.
    // We are dealing with an anonymous, non-authenticated user
}
令牌(
getToken()
)也可以是
null
,因此您可能需要检查它

但是,考虑到您的计算机位于控制器中,并且控制器处理的路由应该位于其中一个防火墙后面。。。通常它不会是空的


如果它是
null
,那么您的设置中还有其他问题,您最好马上抓住它。

上面的答案很好,只是您必须验证getToken()方法是否返回有效的令牌或null。以下是更好的版本:

$user = NULL;
$token = $this->get('security.token_storage')->getToken();

if(NULL !== $token) {
    $user = $token->getUser();
}

if($user instanceof UserInterface) {
    // logged in user
}

Symfony版本3.4.6是的,我回答错误仍然存在。在控制器中,检查当前用户是否是UserInterface的instanceof(我假设您使用UserInterface实现登录)if($this->getUser()instanceof UserInterface)//检查用户是否“已完全验证”//if true access else loginAlso,可能没有代币。最好使用安全助手。用户在使用多个防火墙时通常使用的字符串,并且您只登录了一个防火墙“匿名”在其他地方。无论如何,投票吧。只是为了澄清。是的,我想让代码尽可能接近他们已经在使用的代码。他们还可以检查令牌是否为null,但这不是他们遇到的问题,他们认为应该关注这个问题。无论如何,我将编辑答案以提及这些内容。我已经提出了建议,错误仍然出现在同一行($user=…)$logged=$this->get('security.token_storage')->getToken()->getUser();如果($logged instanceof UserInterface){$messageException=$this->get('translator')->trans('No se ha encontrado el usuario');抛出$this->createNotFoundException($messageException);}$user=$em->getRepository('AppBundle:user')->find($logged->getId())@Nicolas查看编辑答案中的修复是否解决了问题。如果没有,请查看是否可以以更可读的方式提供代码。甚至可能在pastebin.com上。但我无法解析注释中的代码,抱歉。使用您的解决方案,我已在程序未登录时将其导入IF,但我仍然无法将其重定向到登录表单。我写了一行:返回新的重定向响应($this->router->generate('app_homepage');我得到的错误是:“调用null上的成员函数generate()。我希望这次你能读得好。谢谢。“用户”可能是“匿名”字符串.Ka boom错误500.您的业务已结束,您的客户端已消失。Emix您的权限。$user可能是字符串,因此您必须测试它是否为对象。我将更新我的答案。但在某些情况下,令牌可能为空,正如您在此处所读到的:Frank,如果您阅读了您正在链接的注释,您将看到令牌可能为空的情况仅此而已不适用于此场景:这是一个控制器,而不是一个事件侦听器,可以在“请求太早”时执行,并且它不是您没有auth的CLI命令;而且,由于他们正在检查用户是否经过身份验证,因此它遵循的路径是在安全防火墙后面。如果不是,这意味着应用程序配置错误,你无论如何也不想在这种状态下运行。谢谢@yivi,但如果我记得很清楚的话,它也可能发生在自定义错误页面上,因此我认为最好也验证令牌,而且在任何情况下都不会错。是最终的“更好”版本。更好的方法是使用它,而不是为了不重新发明轮子而重写它