Я пытаюсь создать центральный контроллер cron в Symfony, аналогичный тому, что делает Laravel. Я нашел этот замечательный компонент: https://github.com/rewieer/TaskSchedulerBundle, но я не могу заставить его работать.
Документация для Symfony 2, и я использую 4.3
Я пытался адаптировать то, что понял.
AppKernel.php не существует, поэтому я использовал app / config / bundles.php
Похоже на это
<?php
return [
...
Rewieer\TaskSchedulerBundle\RewieerTaskSchedulerBundle::class => ['all' => true],
];
Тогда я создал свой класс задач
<?php
namespace App\Tasks;
use Rewieer\TaskSchedulerBundle\Task\AbstractScheduledTask;
use Rewieer\TaskSchedulerBundle\Task\Schedule;
class UpdateDFsize extends AbstractScheduledTask {
/**
* Set the Cron Schedule
*
* @param Schedule $schedule
*/
protected function initialize(Schedule $schedule) {
$schedule
->everyMinutes(5); // Perform the task every 5 minutes
}
/**
* Run Update DFsize cron
*
* @return string|null result of the cron or null if fails
*/
public function run() : ?string {
//Do some stuff
return $result;
}
}
Вместо использования service.xml я создал service.yaml
Я добавил конфиг, предложенный в комментарии (я потерял ссылку)
parameters:
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
#Added per recommendation
**_instanceof:
Rewieer\TaskSchedulerBundle\Task\TaskInterface:
tags: ['ts.task']
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
Наконец я пытаюсь запустить
Прежде чем вы спросите, да, я изменил путь / к / проекту
php /path/to/project/bin/console ts:run >> /dev/null 2>&1
Но ничего не происходит, я не получаю ответа в консоли и не знаю, как отладить его с помощью xdebugger + phpstorm
Любой совет будет принят с благодарностью.
Для проверки моего cron я создал контроллер
Этим я подтвердил, что код правильный
<?php
namespace App\Controller;
use App\Tasks\UpdateDFsize;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class CronController
{
public function __construct() {
}
/**
* @Route("/cron/dfsize", name="index")
* @param UpdateDFsize $updateDFsize
* @return Response
*/
public function updateDFsize(UpdateDFsize $updateDFsize) : Response {
$response = $updateDFsize->run();
return new Response($response, Response::HTTP_OK);
}
}
EDIT:
Ответ от @NicoHaase идеально подходит. Тем не менее, мне нужно было, чтобы cron-контроллер выполнялся извне, поэтому я следовал этой документации Symfony https://symfony.com/doc/current/console/command_in_controller.html и изменил свой контроллер для внешнего доступа
<?php
namespace App\Controller;
use http\Exception;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;
class CronController
{
/**
* @Route("/cron", name="cron")
* @param KernelInterface $kernel
* @return Response
* @throws \Exception
*/
public function runCron(KernelInterface $kernel) : Response {
$application = new Application($kernel);
$application->setAutoExit(false);
//Run the command
$input = new ArrayInput([
'command' => 'ts:run',
]);
//Prepare output
$output = new BufferedOutput();
$application->run($input, $output);
$content = $output->fetch();
return new Response($content);
}
}