PHP.GT

Running the runner

In WebEngine applications, the cron runner automatically starts with gt run, and can be executed manually with gt cron.

In standalone applications, the simplest way to use this library is through the bundled CLI command:

vendor/bin/cron

Run it from the project root so it can find the local crontab file and cron/ directory.

Default behaviour

With no flags, the runner:

  • reads ./crontab
  • runs any jobs that are due right now
  • prints the current local time
  • prints the next due time
  • exits

If there is no crontab file, it reports that and exits without running jobs.

--watch

Use --watch to keep the process alive:

vendor/bin/cron --watch

In watch mode, the runner sleeps until the next due job, runs it, prints an update, and continues.

This is the usual choice during development if we want the scheduler to stay active in the background.

--now

Use --now when we want to run every job immediately once before normal scheduling begins:

vendor/bin/cron --now

This is useful for checking that the commands themselves work, especially in development.

It can also be combined with watch mode:

vendor/bin/cron --now --watch

--now can also receive one job name to run only that matching job:

vendor/bin/cron --now load-wikis

The name is the shortened command name shown in runner output. For example:

  • load-wikis matches load-wikis, load-wikis.php, or cron/load-wikis.php.
  • Digest::send matches App\Task\Digest::send(...).

If no job matches, the command exits with an error instead of running anything.

--validate

To check the file without running jobs:

vendor/bin/cron --validate

This is helpful in CI, deployment scripts, or just before committing a new schedule.

--file

To use a file other than ./crontab:

vendor/bin/cron --file crontab.staging

The file is resolved relative to the current working directory.

Reading the output

When jobs run, the CLI prints summaries such as:

  • the current local time
  • how many jobs just ran
  • a shortened display name for each job
  • the next scheduled run time
  • the next command due

If local time is different from UTC, the current time and next run time include UTC in brackets:

Current time: 16:49:52 (15:49:52 UTC)
Just ran 0 jobs
Next job at: 17:00:00 (16:00:00 UTC) [build-index]

The command due next is shown in square brackets after the time.

In watch mode it also prints Waiting... after each cycle.

Child command output

The CLI status messages described above are separate from the command’s own stdout and stderr.

By default, the bundled runner discards child process output. This keeps the scheduler output tidy, but it also means echo inside a cron script is not usually the right way to observe success.

If we are embedding the library in PHP ourselves, we can choose a different ScriptOutputMode through JobRepository:

  • ScriptOutputMode::DISCARD
  • ScriptOutputMode::INHERIT
  • ScriptOutputMode::CAPTURE

Using the runner from PHP

The CLI is convenient, but the library can also be used directly:

use GT\Cron\RunnerFactory;

$runner = (new RunnerFactory())->createForProject(__DIR__);
$runner->run();

To ignore the schedule and run all jobs immediately:

$runner->runAll();

To run only selected jobs immediately, pass a matcher that receives the original crontab command string:

$runner->runMatching(
	fn(string $command):bool => str_contains($command, "load-wikis")
);

If we need more control, we can set a callback that receives progress data after each cycle:

$runner->setRunCallback(
	function(
		int $jobsRan,
		?DateTime $nextRun,
		bool $continue,
		array $runCommandList,
		?string $nextCommand,
	):void {
		// Log or display status here.
	}
);

Move on to Static functions and shell commands to see how the command part of each crontab line is interpreted.