我需要每2小时运行一次控制器方法。我读到某处您需要创建命令并使用CRON运行该命令。是对的吗?
MY COMMAND:
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Routing\Annotation\Route;
class RunCommand extends Command
{
// the name of the command (the part after "bin/console")
protected static $defaultName = 'app:run';
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
echo 'BEGIN';
$controller = new \AppBundle\Controller\DefaultController();
$controller->storeAction();
echo 'END';
}
}
MY CONTROLLER:
/**
* @Route("/to-db", name="to-db")
*/
public function storeAction()
{
$entityManager = $this->getDoctrine()->getManager();
$data = new Skuska();
$data->setName('Keyboard');
$entityManager->persist($data);
$entityManager->flush();
// die();
}
我的错误:在ControllerTrait.php第424行:调用成员函数has()为null
我的代码正确吗?如何使用cron运行方法?
我不想使用其他捆绑软件。我想自己编程
答案 0 :(得分:3)
如注释中所述,您应将逻辑移出控制器并移入服务,并在命令和控制器中使用该服务。
使用默认的服务自动加载配置,您甚至不必关心服务声明。您的命令将自动成为服务,并且您可以将其他服务注入其中。
https://symfony.com/doc/current/console/commands_as_services.html
对于控制器,您甚至不需要使用特定的构造函数。
https://symfony.com/doc/current/controller.html#fetching-services
<?php
// AppBundle/Service/StoreService.php
use AppBundle\Entity\Skuska;
use Doctrine\ORM\EntityManager;
class StoreService
{
/** @var EntityManager */
private $entityManager;
/**
* StoreService constructor.
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function store()
{
$data = new Skuska();
$data->setName('Keyboard');
$this->entityManager->persist($data);
$this->entityManager->flush();
}
}
<?php
// AppBundle/Controller/StoreController.php
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Service\StoreService;
class StoreController extends Controller
{
/**
* @Route("/to-db", name="to-db")
* @param StoreService $storeService
* @return Response
*/
// Hinting to you service like this should be enough for autoloading.
// No need for a specific constructor here.
public function storeAction(StoreService $storeService)
{
$storeService->store();
return new Response(
// Return something in you response.
);
}
}
<?php
// AppBundle/Command/RunCommand.php
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use AppBundle\Service\StoreService;
class RunCommand extends Command
{
protected static $defaultName = 'app:run';
/** @var StoreService */
protected $storeService;
/**
* RunCommand constructor.
* @param StoreService $storeService
*/
public function __construct(StoreService $storeService)
{
$this->storeService = $storeService;
parent::__construct();
}
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
echo 'BEGIN';
$this->storeService->store();
echo 'END';
}
}