Php FOS用户包向注册添加所需功能
我觉得我已经用尽了Google和Fos UserBundle的文档来搜索一种在注册新用户时初始化基本实体的方法。我已经重写了RegistrationController:register方法,正在尝试初始化并向用户添加一个名为“Humidor”的实体。这就是它当前的显示方式Php FOS用户包向注册添加所需功能,php,symfony,model-view-controller,fosuserbundle,registration,Php,Symfony,Model View Controller,Fosuserbundle,Registration,我觉得我已经用尽了Google和Fos UserBundle的文档来搜索一种在注册新用户时初始化基本实体的方法。我已经重写了RegistrationController:register方法,正在尝试初始化并向用户添加一个名为“Humidor”的实体。这就是它当前的显示方式 <?php namespace UserBundle\Controller; use Symfony\Component\HttpFoundation\RedirectResponse; use FOS\U
<?php
namespace UserBundle\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
use AppBundle\Entity\Humidor;
use Symfony\Component\HttpFoundation\Request;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
class RegistrationController extends BaseController
{
public function registerAction(Request $request)
{
/** @var $formFactory FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** @var $userManager UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
/** @var $dispatcher EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$humidor = new Humidor();
$user->addHumidor($humidor);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->getParameter('fos_user.registration.confirmation.enabled')
? $this->generateUrl('fos_user_registration_confirmed')
: $this->generateUrl('fos_user_profile_show');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
if (null !== $response = $event->getResponse()) {
return $response;
}
}
return $this->render('FOSUserBundle:Registration:register.html.twig', array(
'form' => $form->createView(),
));
}
}
首先要做的事情:因为你所做的就是在一个统一的用户身上安装一个新的Humidor()
。也可以将此部分作为构造函数的一部分。这类似于条令建议使用集合的方式:
class User extends BaseUser
{
public function __construct(Humidor $humidor = null)
{
// Doctrine recommends this for ToMany-associations:
$this->humidors = new ArrayCollection();
if (null === $humidor) {
$humidor = new Humidor();
}
$this->addHumidor($humidor);
}
// [...the rest of your code...]
}
这样,即使在未初始化的用户上,也可以始终使用此对象。不管你需要什么,你都可以玩这个。你可以传递一个数组而不是一个“默认”的湿度计,或者你也可以调整getHumidors()
来检查它是否为空,然后创建默认的湿度计。在任何情况下,在用户内部处理此问题都可以让您轻松更改一个类(而不是调用addHumidor()
的所有控制器)中的默认行为。这将确保您始终可以使用(默认?)空的humidor
第二,关于:
我注意到php storm建议了所有默认的用户方法,但没有一个来自我的自定义用户,所以显然有些地方出了问题
PhpStorm只是猜测方法的输出,因此它是什么类型的对象。在您的例子中,您使用的是EntityManager,它在接口中引用的是UserInterface,它也在doc块中使用
如果您检查,您会注意到docblock包含@return UserInterface
。这就是PhpStorm获取用户管理器返回的对象类型的地方,并且因为您的用户类具有比接口更多的方法,例如addHumidor
PhpStorm将不知道它们。如果您想告诉PhpStorm有一个具体的对象t如果有更多的方法(即您的用户类),您可以在调用createUser时执行以下操作:
/** @var $user AppBundle\Entity\User */
$user = $userManager->createUser();
这应该会覆盖PhpStorms以前对该类型的假设,然后在下面的if条件中找到您的方法。如果您接受我的第一个建议,您不必这样做,因为您无论如何都不必调用addHumidor()
方法
至于为什么必须这样做可能有点冗长,基本要点是,php是动态类型的,PhpStorm永远不可能100%知道一个方法在运行时会返回什么,因为php没有强制一个方法总是返回相同的东西。这就是为什么PhpStorm必须猜测并且通常使用docblock(或使用PHP7:指定的返回类型)作为最权威的源代码,因为这显然是开发人员想要返回的,也是应该期望的。第一件事:因为您所做的就是
新的Humidor()
在统一化用户上。您也可以将此部分作为构造函数的一部分。这与Doctrine建议使用集合的方式类似:
class User extends BaseUser
{
public function __construct(Humidor $humidor = null)
{
// Doctrine recommends this for ToMany-associations:
$this->humidors = new ArrayCollection();
if (null === $humidor) {
$humidor = new Humidor();
}
$this->addHumidor($humidor);
}
// [...the rest of your code...]
}
这样,即使在未初始化的用户上,您也可以始终使用此对象。您可以根据需要使用此对象。您可以传递数组而不是单个“默认”湿度计,也可以调整getHumidors()
检查它是否为空,然后创建默认的。在任何情况下,在用户内部处理此问题都可以让您轻松更改一个类中的默认行为(而不是调用addHumidor()
的所有控制器)。这将确保您始终可以使用(默认?)空的humidor
第二,关于:
我注意到php storm建议了所有默认的用户方法,但没有一个来自我的自定义用户,所以显然有些地方出了问题
PhpStorm只是猜测方法的输出,因此它是什么类型的对象。在您的例子中,您使用的是EntityManager,它在接口中引用的是UserInterface,它也在doc块中使用
如果您检查,您会注意到docblock包含@return UserInterface
。这就是PhpStorm获取用户管理器返回的对象类型的地方,并且因为您的用户类具有比接口更多的方法,例如addHumidor
PhpStorm将不知道它们。如果您想告诉PhpStorm有一个具体的对象t如果有更多的方法(即您的用户类),您可以在调用createUser时执行以下操作:
/** @var $user AppBundle\Entity\User */
$user = $userManager->createUser();
这应该会覆盖PhpStorms以前对该类型的假设,然后在下面的if条件中找到您的方法。如果您接受我的第一个建议,您不必这样做,因为您无论如何都不必调用addHumidor()
方法
至于为什么必须这样做可能有点冗长,基本要点是,php是动态类型的,PhpStorm永远不可能100%知道一个方法在运行时会返回什么,因为php没有强制一个方法总是返回相同的东西。这就是为什么PhpStorm必须猜测并且通常使用docblock(或使用PHP7:指定的返回类型)作为最权威的源代码,因为这显然是开发人员想要返回的,也是应该期望的。您是否尝试运行代码?PhpStorm显示警告的事实并不一定意味着代码无法工作(警告可能与PhpStorm无法推断用户管理器的
createUser()
方法返回的具体类有关)。如果php只建议默认方法,这可能意味着您的一个注释映射到基本用户上,我建议您查看createUser
函数以了解te注释是什么。正如@xabbuh所说,这并不是因为php storm发出了不起作用的警告。如果在case中没有这些东西很可能,createUser
函数返回的是基本用户obj,而不是自定义用户obj