Installation
composer require alpixel/cronbundle:^2.0
Register the bundle in AppKernel.php:
new Alpixel\Bundle\CronBundle\CronBundle(),
Database Setup Run migrations or schema update:
php app/console doctrine:migrations:diff
php app/console doctrine:migrations:migrate
or
php app/console doctrine:schema:update --force
First Use Case: Create a Cron Job
Create a Symfony Command class and annotate it with @CronJob:
use Alpixel\Bundle\CronBundle\Annotation\CronJob;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @CronJob(value="PT1H", startTime="today 12:00")
*/
class MyCronCommand extends Command
{
protected function configure()
{
$this->setName('app:my-cron-job');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Running every hour!');
}
}
Scan and Run Scan for new cron jobs:
php app/console cron:scan
Run the cron jobs:
php app/console cron:run
Server-Side Cron Setup Add a cron entry on your server (e.g., every 5 minutes):
*/5 * * * * /usr/bin/php /path/to/app/console cron:run --env=prod
Developing New Cron Jobs
Symfony\Component\Console\Command\Command or Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand.@CronJob(value="PT1H", startTime="today 12:00") to define frequency and initial run time.DateInterval format for value (e.g., PT1H for hourly, P1D for daily).cron:scan after adding new jobs to register them in the database.Integrating with Existing Commands
@CronJob without modifying their logic./**
* @CronJob(value="P1D")
*/
class ExistingCommand extends Command { ... }
Dynamic Configuration
class DynamicCronCommand extends Command
{
private $config;
public function __construct($config)
{
$this->config = $config;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Running with config: ' . $this->config);
}
}
Logging and Monitoring
execute() for debugging:
$this->getHelper('dialog')->write('Cron job executed at ' . date('Y-m-d H:i:s'));
$logger = $this->getContainer()->get('logger');
$logger->info('Cron job executed', ['command' => $this->getName()]);
Environment-Specific Jobs
--env flag in cron setup to run jobs in specific environments (e.g., prod).*/10 * * * * /usr/bin/php /path/to/app/console cron:run --env=prod
ContainerAwareCommand or dependency injection.execute() or using cron:run with --dry-run.try {
// Risky operations
} catch (\Exception $e) {
$this->getLogger()->error('Cron job failed', ['error' => $e->getMessage()]);
}
CLI Environment Limitations
Request, Router) are unavailable.Mailer or EntityManager directly or configure them for CLI.$urlGenerator = $this->getContainer()->get('router')->getContext()->getSchemeAndHttpHost();
Time Zone Issues
startTime uses the server’s time zone. Ensure consistency with your application’s time zone.date.timezone in php.ini or use DateTime with explicit time zones:
$startTime = new \DateTime('today 12:00', new \DateTimeZone('Europe/Paris'));
Database Locking
cron:run executions may cause race conditions if not handled.$entityManager = $this->getContainer()->get('doctrine')->getManager();
$entityManager->beginTransaction();
try {
// Critical operations
$entityManager->commit();
} catch (\Exception $e) {
$entityManager->rollBack();
throw $e;
}
Cron Job Overlaps
PT5M) may overlap if execution time exceeds the interval.Annotation Caching
@CronJob, run cron:scan to update the database. Forgetting this step causes jobs to appear "missing."php app/console cache:clear
Dry Runs
Use --dry-run to simulate cron execution without modifying the database:
php app/console cron:run --dry-run
Logging Enable debug mode to log cron job scans and executions:
php app/console cron:scan -v
php app/console cron:run -vv
Database Inspection
Check the cron_job table for registered jobs:
SELECT * FROM cron_job;
next_run_at and interval values match expectations.Command-Line Arguments
Pass arguments to cron jobs via execute() or use setArguments() in tests:
$command = new MyCronCommand();
$command->setArguments(['--option' => 'value']);
$command->run(new ArrayInput([]), new BufferedOutput());
Custom Storage
Override the default Doctrine storage by implementing Alpixel\Bundle\CronBundle\Model\CronJobInterface and configuring a custom repository.
Event Listeners
Subscribe to cron job events (e.g., cron.job.before, cron.job.after) via Symfony’s event dispatcher:
$dispatcher->addListener('cron.job.before', function ($event) {
// Pre-execution logic
});
Dynamic Intervals
Modify intervals at runtime by updating the cron_job table or using a service to fetch dynamic values:
$interval = $this->getContainer()->get('my_service')->getDynamicInterval();
$cronJob->setInterval($interval);
Parallel Execution For long-running jobs, consider splitting tasks or using a queue system (e.g., Symfony Messenger) to avoid blocking the cron process.
Environment Variables
Load cron job configurations from environment variables (e.g., .env):
$interval = getenv('CRON_JOB_INTERVAL') ?: 'PT1H';
How can I help you explore Laravel packages today?