PHP Process¶
Pausing¶
If you need to pause your program to wait for external thing to happen (or any other reason), you can pause it this way:
You can use any unit of period except months because it's not a absolute value.
Info
If you want to wait for years it will compute that as 365
days. But if you need to do this there may be a design problem in your program.
Handling CLI Signals¶
Any process can receive signals to tell them a user (or the system) wants to shut them down allowing the process to terminate gracefully (1).
- This is the prevalent usage, but there are more.
For example let's say you need to import a large csv file into a database but you want to be able to stop it gracefully. You can do:
use Innmind\Signals\Signal;
use Innmind\Filesystem\{
File,
File\Content\Line,
Name,
};
use Innmind\Url\Path;
use Innmind\Immutable\{
Sequence,
Predicate\Instance,
};
$signaled = false;
$stop = static function() use (&$signaled): void {
$signaled = true;
};
$os
->process()
->signals()
->listen(Signal::interrupt, $stop);
$os
->filesystem()
->mount(Path::of('data/'))
->get(Name::of('users.csv'))
->keep(Instance::of(File::class))
->map(static fn(File $file) => $file->content()->lines())
->toSequence() #(1)
->flatMap(static fn(Sequence $lines) => $lines)
->takeWhile(static function() use (&$signaled) {
return !$signaled;
})
->foreach(static fn(Line $line) => importToDb($line));
$os
->process()
->signals()
->remove($stop);
Maybe<Sequence>->toSequence()->flatMap(fn($sequence) => $sequence)
is a way to swallow the fact that the file may not exist.
This way if a user sends a signal to interrupt the script, it will:
- pause the execution
- call the
$stop
function - modify the
$signaled
flag - resume the execution
- the next line that is attempted to be read won't be done because of
takeWhile
Tip
You can specify multiple listeners for a single signal and they'll be executed in the order you added them.