symfony - Symfony 和 Api-Platform:在控制器之外使用 Doctrine 和其他服务
问题描述
你好 Stackoverflow
我们遇到了 Symfony 和 API-PLATFORM 的问题。我们尝试了很多东西,但找不到任何解决方案。我们在使用 stackoverflow 上已经给出的答案以及他们遇到的与此问题相关的 git 问题时遇到了困难。这就是为什么这不是任何形式的重复,因为那些遗憾地没有帮助我们。
问题如下。我们src
的 api-platform 文件夹中有标准结构。
- src
-- Annotation
-- Controller
-- Doctrine
-- Emails
-- Entity
-- EventListener
-- EventSubscriber
-- Filters
-- Repository
-- Security
-- Utils
所以这是我们的问题开始了。我们有一些类,它们只是一些易于使用的实用程序。那些在utils
文件夹里。这个问题是关于 Utils 文件夹中名为Phone
. (命名空间App\Utils\Phone
)。这里的事情是,我们需要EntityManager
在这个 Utils 类中使用 ,因为我们需要存储一些数据(临时)。我们将使用以下代码执行此操作(在控制器中工作)
$em = $this->getDoctrine()->getManager();
$em->persist($smsStore);
$em->flush();
现在错误来了:这里甚至不存在教义。找不到。这里的问题是:我们如何在控制器之外使用 Doctrine EntityManager?我们尝试使用默认的 AbstractController 进行扩展,但这不正确且不起作用。
当我们想使用我们的安全类来获取当前用户时,也会发生同样的事情。( $this->security->getUser()
)。即使我们像使用一样导入它。use Symfony\Component\Security\Core\Security;
.
我们希望我们对这个问题很清楚。我们有点绝望,因为几天后我们仍在寻找解决方案。我们使用 PHP 版本7.1.3
和 API-PLATFORM 版本1.1
(composer.json)
编辑1:不存在是关于未定义的方法(getDoctrine)。我们尝试了一些方法来实现这一点。例如使用 AbstractController 来扩展类。另一个有效的解决方案是通过函数传递 DoctrineManager。然而,这不是一个好的做法。
编辑 2:请求的 AuthController 片段。它显示了我们如何使用电话实用程序。是不是我需要在围绕以下代码的这个函数中实现 EntityInterface?
$phone = new Phone();
$phone->overwriteUser($this->getUser());
$phone->newRecipient("4917640733908");
$phone->setBody("Hello, this is a test.");
解决方案
实体管理器可以使用依赖注入(DI)模式来处理。这种模式完全集成在 Symfony 中。这就是 Symfony 的有趣和神奇之处。
所有实现接口的类都可以通过依赖注入获得。使用 Symfony4+,自动配置被激活。这似乎很复杂,但对于最终的开发人员来说,这很容易。这是一个使用您的电话类执行此操作的简单示例,这似乎是您实现业务逻辑的模型。
class Phone
{
private $entityManager;
//The entity manager will be provided to your constructor with the dependency injection.
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function save($smsStore)
{
//you own logic go here
//here is the magic part, the entityManager is available, connected, ready to use.
$this->entityManager->persist($smsStore);
$em->flush();
}
}
当您调用 Utils 类方法时,DI 将自动构造它,您将能够使用它的属性,在本例中为实体管理器。
如果你想在控制器中使用你的类,你可以通过在其构造函数中添加电话类来实现:
class AuthController extends AbstractController
{
public function __construct(Phone $phoneUtils)
{
$this->phoneUtils = $phoneUtils;
}
public function someAction()
{
//your own logic here
//here is the magic part, the phone Utils is ready, it imports the entitymanager
//when you want to save your smsStore, simply call it
$this->phoneUtils->save($smsStore);
}
}
您使用的是 Api-Platform,没问题!您可以在其他类(如 DataPersisters)或 EventListeners 中重现此设计模式。如果您查看ApiPlateform 文档中的此示例,您可以看到作者如何在他的事件侦听器中获取 Swiftmailer 管理器。只需用 EntityManagerInterface 或 Phone utils 类替换 swiftmailer。
(在控制器中,它存在一种最简单的方法来检索电话实用程序类)
class AuthController extends AbstractController
{
//Do That: ADD Phone $phoneUtils as an argument in the method
public function someAction(Phone $phoneUtils)
{
//your own logic here
//Do not do that: $phoneUtils = new Phone();
//Magic! when you want to save your smsStore, simply call it
$phoneUtils->save($smsStore);
}
}
如果您想获得一个自动装配的类(如安全层),您可以这样做。要查找可以自动装配的类,有一些提示:
symfony console debug:autowiring
symfony console debug:autowiring Security
symfony console debug:autowiring AuthorizationChecker
它将返回与您的搜索相对应的所有类。
(如果你不使用 symfony 可执行文件,你可以用 php bin/console debug:autowiring 替换它)
推荐阅读
- asp.net-core - 如何正确地将 asp.net 核心模型状态错误反序列化为 xamarin 形式的对象
- javascript - 尝试在js中添加图像转换器
- github-actions - Github 操作触发错误的工作流程作为 PR 创建的状态检查
- tsqlt - tSQLt.run 在一个查询窗口中什么都不做,但在另一个窗口中起作用
- node.js - 如何获取集合并加入参考字段中的数据?
- dynamic-programming - 到达第 n 个楼梯
- c - 在c中引用双指针的属性
- python - 如何检查输入后是否使用了字母?
- php - 如何将安装在主机服务器上的 phpmyadmin 连接到正在运行的 docker 容器内的 maria db?
- scala - 如何将案例类作为变量传递给ScalaReflection