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-wikismatchesload-wikis,load-wikis.php, orcron/load-wikis.php.Digest::sendmatchesApp\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::DISCARDScriptOutputMode::INHERITScriptOutputMode::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.