
Sometimes, when developing web applications, we tend to invoke external programs from the operating system to obtain a specific result needed for our app.
Invoking an external process is an essential aspect in many applications. In PHP usually to invoke an external system process there are some functions like shell_exec(), exec() or passthru().
In Laravel 10 there are a new class dedicated for this purpose which is the Process facade. The Process facade is a wrapper behind symfony Process component. In this article we will take a look at the Process class.
Executing Processes
The Process class available by default in Laravel 10 under Illuminate\Support\Facades namespace. The Process::run() method can be used to call external process:
use Illuminate\Support\Facades\Process; $result = Process::run('ls -la');
Process::run() return an instance of Illuminate\Contracts\Process\ProcessResult
The ProcessResult contract contains several methods to deal with the result, for example to get the real output there are ProcessResult::output() like so:
dd($result->output()); drwxrwxr-x 13 sami sami 4096 أغس 23 08:22 .\n drwxr-xr-x 55 sami root 4096 أغس 23 08:18 ..\n drwxrwxr-x 7 sami sami 4096 أغس 10 10:19 app\n -rwxr-xr-x 1 sami sami 1686 أغس 10 10:19 artisan\n .... ....
To check the result success or failure there are some methods like:
$result->failed() $result->successful()
To get the result exitCode:
$result->exitCode()
if($result->successful()) { return $result->output(); }
Real world example: Calling Image Processor Program
A common use case is to invoke image processing software i.e image resizing or cropping.
$result = Process::run("convert '/Desktop/computer.jpg' -resize 120x120 /Desktop/thumbnail.png"); if($result->successful()) { dd($result->output()); } else { dd($result->exitCode(), $result->errorOutput()); }
Here i am calling the convert command in the Imagick image processing software to resize a jpg photo to a smaller png version. I am passing the full source and destination image paths:
convert '/Desktop/computer.jpeg' -resize 120x120 /Desktop/thumbnail.png
If the operation successful it will generate the resized image otherwise it will print the output exit code and error output message using $result->errorOutput() method. an exitcode greater than zero meaning that the operation failed.
For instance if the source image path is invalid it will trigger an error like so:
convert-im6.q16: unable to open image `/home/Desktop/computer.jpeg': No such file or directory @ error/blob.c/OpenBlob/2924.\n
You can customize the failure behavior using the throw() method on the ProcessResult facade:
$result = Process::run("convert '/Desktop/computer.jpg' -resize 120x120 /Desktop/thumbnail.png")->throw();
Here if an error occurs it will throw Illuminate\Process\Exceptions\ProcessFailedException
Process Options
Process class provides some options when working with external commands:
- working directory path:
Process::path('D:\Org\')->run('convert image.jpg converted.png');
Process::path('/var/www/html/app')->run('convert image.jpg converted.png');
You can customize the working directory path using Process::path() method. This is helpful in some os like windows.
- Timeout:
$result = Process::timeout(200)->run('git add .');
Default timeout for executing process is 60 seconds and after it will throw ProcessTimeoutException. However we can customize this using the timeout() method.
Also you can disable timeout using another method forever():
$result = Process::forever()->run();
- Environment Variables:
Sometimes the process in order to run it depends on some environment variables initialized before, you can do that using the env() method:
$result = Process::env(['NODE_PATH' => 'C:\\Program Files\\node'])->run('node app.js')
The env() method accepts an array of env vars you may provide prior to executing the process.
This is some of the basic usage of the Process class, you can learn more and explore other options in laravel docs.