如何从控制器在后台执行Symfony命令

如何从控制器在后台执行Symfony命令,symfony,asynchronous,symfony4,Symfony,Asynchronous,Symfony4,我有一个需要很长时间才能运行的命令(它会生成一个大文件) 我想使用一个控制器在后台启动它,而不是等到它的执行结束后才渲染视图 可能吗?如果是,如何进行 我认为这门课很有用,但文档上说: 如果在子进程有机会完成之前发送响应,服务器进程将被终止(取决于您的操作系统)。这意味着您的任务将立即停止。运行异步进程与运行在其父进程之后仍然存在的进程不同 我用评论中建议的@msg解决了我的问题 为此,我必须: 执行composer require symfony/Messenger 创建自定义日志实体以跟踪

我有一个需要很长时间才能运行的命令(它会生成一个大文件)

我想使用一个控制器在后台启动它,而不是等到它的执行结束后才渲染视图

可能吗?如果是,如何进行

我认为这门课很有用,但文档上说:

如果在子进程有机会完成之前发送响应,服务器进程将被终止(取决于您的操作系统)。这意味着您的任务将立即停止。运行异步进程与运行在其父进程之后仍然存在的进程不同


我用评论中建议的@msg解决了我的问题

为此,我必须:

  • 执行
    composer require symfony/Messenger
  • 创建自定义日志实体以跟踪文件生成
  • 为我的文件生成创建自定义消息和自定义消息处理程序
  • 在我的控制器视图中发送消息
  • 将我的命令代码移动到服务方法
  • 在我的MessageHandler中调用服务方法
  • 运行
    bin/console messenger:consume-vv
    处理消息
这是我的密码:

自定义日志实体 我使用它在视图中显示是否正在生成文件,并在生成完成后让用户下载文件

namespace-App\Entity;
使用条令\ORM\Mapping作为ORM;
/**
*@ORM\Entity(repositoryClass=“App\Repository\MyLogForTheBigFileRepository”)
*/
类MyLogForTheBigFile
{
/**
*@ORM\Id()
*@ORM\GeneratedValue()
*@ORM\Column(type=“integer”)
*/
私人$id;
/**
*@ORM\Column(type=“datetime”)
*/
私有$generationDateStart;
/**
*@ORM\Column(type=“datetime”,nullable=true)
*/
私有$generationDateEnd;
/**
*@ORM\Column(type=“string”,length=200,nullable=true)
*/
私有$filename;
/**
*@ORM\manytone(targetEntity=“App\Entity\User”)
*@ORM\JoinColumn(nullable=false)
*/
私人发电机;
公共函数{u构造(){}
//属性的getter和setter
// ...
// ...
}
控制器 我收到表单提交并发送一条消息,该消息将运行文件生成

/**
*@返回视图
*@param Request$请求该请求。
*@Route(“/generate/big file”,name=“generate\u big\u file”)
*/
公共函数生成文件操作(
请求$Request,
MessageBusInterface$messageBus,
MyFileService$MyFileService
)
{
//实体经理
$em=$this->getDoctrine()->getManager();
//创建空表单数据对象
$myFormOptionsFDO=新的myFormOptionsFDO();
//表单创建
$myForm=$this->createForm(
MyFormType::类,
$myFormOptionsFDO
);
$myForm->handleRequest($request);
//提交
如果($myForm->isSubmitted()&&&$myForm->isValid())
{
$myOption=$myFormOptionsFDO->getOption();
//使用自定义实体创建数据库日志
$myFileGenerationDate=new\DateTime();
$myLogForTheBigFile=新的myLogForTheBigFile();
$myLogForTheBigFile->setGenerationDateStart($myFileGenerationDate);
$myLogForTheBigFile->setGenerator($this->getUser());
$myLogForTheBigFile->setOption($myOption);
//保存正在使用自定义实体生成的文件
$em->persist($myLogForTheBigFile);
$em->flush();
$messageBus->dispatch(
新生成的ebigfilemessage(
$myLogForTheBigFile->getId(),
$this->getUser()->getId()
));
$this->addFlash(
“成功”,“开始生成大文件…”
);
返回$this->redirectToRoute('bigfiles_list');
}
返回$this->render('Files/generate big file.html.twig'[
'form'=>$myForm->createView(),
]);
}
消息 用于将数据传递给服务


名称空间App\Message;
类GenerateBigFileMessage
{
bigfileid的私有$myLogForTheBigFileId;
私有$userId;
公共函数构造(int$myLogForTheBigFileId,int$userId)
{
$this->myLogForTheBigFileId=$myLogForTheBigFileId;
$this->userId=$userId;
}
公共函数getMyLogForTheBigFileId():int
{
返回$this->myLogForTheBigFileId;
}
公共函数getUserId():int
{
返回$this->userId;
}
}
消息处理程序 处理消息并运行服务

namespace-App\MessageHandler;
使用App\Service\MyFileService;
使用App\Message\GenerateBigFileMessage;
使用Symfony\Component\Messenger\Handler\MessageHandlerInterface;
类GenerateBigFileMessageHandler实现MessageHandlerInterface
{
私有$myFileService;
公共函数构造(MyFileService$MyFileService)
{
$this->myFileService=$myFileService;
}
公共函数调用(GenerateBigFileMessage$GenerateBigFileMessage)
{
$myLogForTheBigFileId=$generateBigFileMessage->getMyLogForTheBigFileId();
$userId=$generateBigFileMessage->getUserId();
$this->myFileService->generateBigFile($myLogForTheBigFileId,$userId);
}
}
服务 生成大文件并更新记录器

public函数generateBigFile($myLogForTheBigFileId,$userId)
{
//获取请求生成的用户
$user=$this->em->getRepository(user::class)->find($userId);
//获取与此生成对应的日志对象
$myLogForTheBigFile=$this->em->getRepository(myLogForTheBigFile::class)->find($myLogForTheBigFileId);
$myOption=$myLogForTheBigFile->getOption();
//生成文件
$fullFilename='my_file.pdf';
// ...
// ...
//更新日志
$myLogForTheBigFile->setGenerationDateEnd(new\DateTime());
$myLogForTheBigFile->setFi