Platform-Independent System Functions
With the Unix-specific functionality out of the way, let's now take a look at those functions that can be used in any platform supported by PHP. These general-purpose PHP functions and language constructs allow the user to execute applications and otherwise interact with the underlying operating system.
Executing Applications from PHP
One of the primary interactions with the operating system is the execution of an external application from within PHP. Unlike the pcntl_exec() function discussed in the Unix-specific section of this chapter, these functions do not terminate PHP. Rather, they offer a wide range of options for executing another application and allow you to have a great deal of control over how the input/output of the application interacts with PHP.
Basic External Application Execution
$command is the external application to execute. When this function is executed, PHP will attempt to call the external application. Upon the external application's termination, the output is returned from the function in full. An example of this function is shown in Listing 22.16, which calls the ls application and outputs the results:
Listing 22.16. Using the shell_exec() Function
<?php $output = shell_exec("ls"); echo $output; ?>
An alternative to the shell_exec() parameter is the backtick operator. This operator is identical to the shell_exec() function in every way and is used in a way similar to a quoted string. Any string enclosed within backtick characters (`) will be executed as an external application with the results of that execution the result of the operation. Thus, Listing 22.15 could also have been written in the following fashion:
<?php echo `ls`; ?>
Although useful, the backtick operator andthe shell_exec() functions are quite limited. For starters, neither method allows us to attain the return value of the executed application. To determine this function, PHP provides the exec() function whose syntax is as follows:
exec($command [, &$output [, &$return_val]]);
$command is the command to execute. The first optional parameter, $output, is a pass-by-reference parameter that will be used to store an array of the output of the command (each line will be an index within the array, newline characters removed). The second optional parameter, $return_val, is another pass-by-reference parameter that will be used to store the integer return value of the executed application. When executed, beyond populating any pass-by-reference variables provided, exec() will return a string containing the last line of the output from the external application.
With this function, we not only can retrieve the output of an external application, but also the return value as shown in Listing 22.17:
Listing 22.17. Executing External Applications Using exec()
<?php exec("ls /foo/", $output, $return_val); echo "The command returned with a exit code of: $return_val\n"; ?>
Another alternative to executing external applications within PHP is the passthru() function. This function executes the specified command and sends the output directly to the user while still providing a means of determining the return value of the external command. The syntax for the passthru() function is as follows:
passthru($command [, $return_val]);
$command is the command to execute and $return_val is a pass-by-reference variable that will be used to store the return value of the executed command. When executed, this function sends the output of the executed command directly to the user and has no return value. An example of the use of passthru() can be found in Listing 22.18:
Listing 22.18. Using the PHP passthru() Function
<?php passthru("ls", $return_val); echo "\n\nThis command executed with a exit code of $return_val\n"; ?>
Single-Direction External Command Pipes
Thus far, when it comes to external commands, we have discussed only those functions that offer relatively little control over how the input is returned to the calling script and no control over how input is sent to the external application. For these purposes, PHP provides a number of functions that allow your scripts to open a pipe between PHP and the command being executed. Using this pipe, your script can read or write to the external application using standard file-access commands.
$command is the command to execute and $mode is the access mode for the pipe. The $mode parameter is similar to the fopen() parameter of the same name in the sense that an external command can be opened in read or write mode. Note that the popen() command is unidirectional, meaning that it can be used only to open a pipe that can read or write (not both). When executed, the popen() function returns a resource that can be used with any of PHP's file-access functions (such as fgets() or fputs()). An example of the popen() function in use is shown in Listing 22.19.
Listing 22.19. Opening a Unidirectional Pipe Using popen()
<?php /* Open the process with a read pipe and output the contents */ $pr1 = popen('ls', 'r'); echo fread($pr1, 1024); /* Open a process with a write pipe (pipes to the standard input) */ $pr2 = popen('php', 'w'); fputs($pr2, '<?php touch("myfile.txt"); ?>'); ?>
In Listing 22.19, we open two different piped processes. The first process (represented by $pr1) is a read-only pipe executing the ls command, from which we read 1,024 bytes of output and echo it to the console. The second piped process (represented by $pr2) is a write-only pipe executing the command-line version of PHP. To this pipe, we use the fputs() function to write a simple PHP script to the standard input of that process. The result of this script's execution is the output of the directory listing, plus the creation of myfile.txt in the current directory.
Although not entirely necessary, just as the fopen() function can have its file handles closed using fclose(), a process can be closed using the pclose() function. This function accepts a single parameter (the process resource to terminate) and has no return value:
Dealing with the System Environment
Along with executing external commands from within PHP, it is also possible to create and read environment variables from within your PHP script. These tasks are accomplished through the use of two functions: getenv() and putenv(). The syntax for the getenv() is as follows:
$varname is a string representing the environment variable to retrieve from the system. Upon execution, the getenv() function returns a string containing the value of the requested environment variable.
$variable is a string of the form "ENV=VALUE", where ENV is the environment variable to set and VALUE is the value to set the environment variable. Note that this function is affected by PHP's safe_mode configuration directive. If PHP is running in safe mode, only those environment variables not contained within the safe_mode_protected_env_vars configuration directive will be allowed to be modified.