Run Shell Commands with Laravel's Process Facade
Sometimes a Laravel application needs to run an external command, such as generating a PDF, processing an image, or executing a maintenance script.
Instead of using PHP's exec() or shell_exec() directly, Laravel provides the Process facade.
Execute a Command
use Illuminate\Support\Facades\Process;
$result = Process::run('php --version');
if ($result->successful()) {
$output = $result->output();
}
Laravel returns a process result that lets you inspect whether the command succeeded, its output, and its exit code.
Set a Timeout
External commands can take longer than expected. You can specify how long Laravel should wait:
$result = Process::timeout(30)
->run('php artisan about');
Here, the process has a 30-second timeout. Laravel's default process timeout is 60 seconds.
Handle Command Failures
You can make Laravel throw an exception when a command fails:
$result = Process::run('php artisan about')
->throw();
If the process exits unsuccessfully, throw() raises an exception rather than letting the failure go unnoticed.
Real-World Example
Imagine you have a script that generates a report:
$result = Process::path(base_path())
->timeout(120)
->run('php scripts/generate-report.php');
if ($result->failed()) {
logger()->error('Report generation failed', [
'error' => $result->errorOutput(),
]);
}
This runs the script from your project directory, limits execution time, and logs the error output if it fails.
When Should You Use It?
- Running external scripts
- Image or document processing
- Invoking command-line utilities
- Integrating tools that don't have PHP libraries
- Running controlled maintenance tasks
Important Security Note
Never concatenate untrusted user input into shell commands. Validate inputs carefully and prefer fixed commands with controlled arguments.
Also, if a task should run independently of the web request, consider dispatching a queued job instead of running a long process inside a controller.