What is different between exec(), shell_exec, system() and passthru() functions in PHP?
Categories:
Understanding PHP's External Command Execution Functions: exec(), shell_exec(), system(), and passthru()

Explore the nuances of PHP's external command execution functions: exec(), shell_exec(), system(), and passthru(). Learn their differences, use cases, and security considerations.
PHP offers several functions to execute external commands on the server's operating system. While they all serve the primary purpose of running a command, their behavior regarding output handling, return values, and blocking mechanisms differs significantly. Understanding these distinctions is crucial for choosing the right function for your specific needs, especially concerning security and performance.
Introduction to PHP Command Execution
Executing external commands can be a powerful feature, allowing PHP scripts to interact with other system utilities, run shell scripts, or perform administrative tasks. However, this power comes with significant security implications. Improper use can lead to command injection vulnerabilities, allowing attackers to execute arbitrary commands on your server. It's vital to always sanitize and validate any user-supplied input before passing it to these functions.

General flow of external command execution in PHP
exec(): Non-Blocking, Last Line Output
The exec() function executes an external program and returns the last line of the command's output. It can optionally capture the full output into an array and the command's return status. Unlike system() and passthru(), exec() does not immediately output results to the browser, making it suitable for tasks where you only need to process the output programmatically.
<?php
$command = 'ls -l';
$output = [];
$return_var = 0;
exec($command, $output, $return_var);
echo "<pre>Last line of output: " . end($output) . "</pre>";
echo "<pre>Full output:\n" . implode("\n", $output) . "</pre>";
echo "<pre>Return status: " . $return_var . "</pre>";
?>
Using exec() to list directory contents and capture full output.
shell_exec(): Returns Full Output as String
The shell_exec() function is similar to the backtick operator (``) in shell scripting. It executes a command and returns the complete output as a single string. If the command fails, it returns NULL. This function is useful when you need the entire output as a single block of text, for example, when parsing log files or command-line tool outputs.
<?php
$command = 'echo "Hello from shell_exec!" && hostname';
$output = shell_exec($command);
if ($output === null) {
echo "<pre>Command failed to execute.</pre>";
} else {
echo "<pre>Full output:\n" . $output . "</pre>";
}
?>
Using shell_exec() to get full command output as a string.
system(): Direct Output to Browser, Returns Last Line Status
The system() function executes the specified command and immediately outputs the result to the standard output (usually the browser). It returns the last line of the command's output if successful, or FALSE on failure. system() is ideal for commands whose output you want to display directly to the user without further processing by the PHP script.
<?php
echo "<pre>Output from system():\n";
$last_line = system('date', $return_var);
echo "\n</pre>";
echo "<pre>Return status: " . $return_var . "</pre>";
echo "<pre>Last line returned by system(): " . $last_line . "</pre>";
?>
Using system() to display the current date directly.
passthru(): Raw Output for Binary Data
The passthru() function is designed to execute external commands and 'pass through' their raw output directly to the browser. This is particularly useful for binary data, such as images, PDFs, or archive files, where you don't want PHP to interfere with the output stream. It also returns the command's exit status. passthru() is often used in conjunction with setting appropriate HTTP headers for file downloads.
<?php
// Example: Displaying an image directly from a command (e.g., 'cat image.jpg')
// For demonstration, we'll use a simple text command.
header('Content-Type: text/plain'); // Set header for text output
echo "<pre>Output from passthru():\n";
passthru('echo "This is raw text from passthru." && cat /etc/os-release', $return_var);
echo "</pre>";
echo "<pre>Return status: " . $return_var . "</pre>";
// For a real-world scenario with binary data, you might do:
// header('Content-Type: image/jpeg');
// passthru('cat /path/to/image.jpg');
?>
Using passthru() to output raw text and system information.

Comparison of PHP External Command Execution Functions
escapeshellarg() or escapeshellcmd() to properly escape arguments and commands to prevent command injection vulnerabilities.Choosing the Right Function
The choice among exec(), shell_exec(), system(), and passthru() depends entirely on your application's requirements:
exec(): Best for when you need to run a command and process its output programmatically, especially if you only care about the last line or need to iterate through an array of lines.shell_exec(): Ideal for when you need the entire output of a command as a single string for parsing or display.system(): Use when you want to execute a command and display its output directly to the user, similar to how a terminal would.passthru(): Specifically designed for commands that generate binary output (like images or archives) that needs to be streamed directly to the client without PHP's intervention.
1. Step 1
Identify your output needs: Do you need the last line, full string, array of lines, or raw binary stream?
2. Step 2
Consider blocking behavior: All these functions block script execution until the command completes. For non-blocking execution, consider proc_open() or backgrounding the process.
3. Step 3
Prioritize security: Always sanitize user input with escapeshellarg() for arguments and escapeshellcmd() for the full command string.
4. Step 4
Error handling: Check the return status ($return_var for exec(), system(), passthru()) or NULL for shell_exec() to detect command failures.
proc_open(). It offers greater flexibility but comes with increased complexity.