March 18th, 2008
570 Part IV: Using PHP for Sysadmin Tasks Features of the reminder tool The reminder tool will offer the following features: . It will process reminders for all users on the system. . All users can have their own set of reminders, which they can manage using configuration files and message templates. . Each reminder can be sent using a separate message template. . Types of reminders supported are daily, weekly, monthly, and yearly. . For each type of reminder, there can be an unlimited number of reminders per user. Now let s implement this tool. Implementing the reminder tool Listing 16-5 shows a configuration file that we will use for our reminder tool. The DEBUG constant will be used for enabling and disabling debug messages. The PASSWD_FILE constant points to the system s password file. You can use a different file, but two fields are required by the reminder system: username and home directory. If you use a custom user list file, make sure it mimics the /etc/passwd file in terms of the formatting and placement of username, and the home directory field. Reading man htpasswdand/or man passwdwill help with managing and mimicking the /etc/passwdfile. The $XMAILER variable is used to name the reminder in an X-header for each mail message sent. This can be set to anything. The USER_REMINDER_DIR constant is used to store the expected name of the user s reminder directory. Each user can have a reminder directory inside the home directory as ~username/%USER_REMINDER_DIR/. For example, ~kabir/reminders is the default reminder directory per the following configuration for the user kabir. Each user s reminder configuration is stored in the reminders.txt file pointed to by the USER_REMINDER_FILE constant. This file must reside in a directory specified by USER_REMINDER_DIR, within a user s home directory. For example, the user sheila, whose home directory is /home/sheila (i.e., ~sheila), can have /home/sheila/ reminders/reminders.txt as the full path for her reminder configuration file. The configuration file is as follows:
Posted in JSP | No Comments »
March 18th, 2008
Chapter 16: Command-Line PHP Utilities 569 Building a Simple Reminder Tool In this day and age, who does not need to be reminded of something? In this section, you will develop a reminder utility that runs on a Linux system as a daily cron job. A cron job is simply another name for a scheduled task. Linux and other UNIX systems have a daemon program called cron, which runs other programs at given intervals. Linux contains predefined cron directories in the main system configuration /etc directory, including the following: . /etc/cron.daily: scripts and programs that are run once a day . cron.hourly: scripts and programs that are run once every hour . cron.monthly: scripts and programs that are run once a month . cron.weekly: scripts and programs that are run once a week You can generally create a symbolic link (symlink) from the program you want to run via cron to one of these directories and get it run on the predefined schedule. If you want to know when an hourly, daily, weekly, or monthly cron job is run from the aforementioned scripts, look at /etc/crontab, which shows the time when these directories are processed by the cron daemon. You might have to consult the crontab manual pages (man crontab) to understand the cryptic time assignments. The user who needs more information on cron should start with the man 5 crontabcommand, which describes the basic syntax of the crontabfile and operation of cronin general. Note that if you are not a privileged user, you will want to explore the cron land cron ecommands for dealing with cronand crontab.Although this section deals mainly with Linux and cron, Windows users can use the Windows Scheduler application to schedule tasks to run at preset time(s). We will develop this reminder tool and symbolically link it inside the /etc/cron.daily so that the reminder tool is run once a day automatically. In most systems, daily tasks are run very early in the morning (for example, 4:00 A.M.). First, let s examine what our reminder system will offer.
Posted in JSP | No Comments »
March 18th, 2008
568 Part IV: Using PHP for Sysadmin Tasks Notice that arguments that do not have a value (such as -h) have a value of 1 in the $cmd array. Since 1 evaluates to TRUE in Boolean expressions, when this array is returned, you can easily find out which command-line arguments were selected. In this script, it uses the built-in isset() function to determine whether a known argument is set, and prints a message indicating the result. For example: ./cmd_options.php -h Returns: You selected help option. This shows that -h has been supplied. To add a new short argument called -z, we can simply update the $CMD_SHORT_OPTIONS list. Similarly, to add a long argument called -zero, we can add this argument in $CMD_LONG_OPTIONS. For example, to allow a new long argument called -count that expects a value, we can add count= in the following array: $CMD_LONG_OPTIONS = array( help , size= , count= ); Then we can write code to determine whether the user has chosen this argument or not. For example: if (isset($cmd[ count ])) { echo You entered count value of . $cmd[ count ] . n ; } Now that you know how to deal with command line PHP scripting along with argument handling, let s develop some interesting command-line scripts. In the following section, you will develop a simple reminder tool. Most chapters in this book refer you to the accompanying CD-ROM for source listings. Because the tools discussed in this chapter are very small, we include the source listing so that you can see the entire code while reading the chapters.
Posted in JSP | No Comments »
March 17th, 2008
Chapter 16: Command-Line PHP Utilities 567 The syntax for short arguments in Console_Getopt::getopt() is fairly simple. List each short argument, order doesn t matter. If an argument requires a parameter (like s in the listing above) you follow it with a colon (as we did above). If the parameter is optional, you add two colons. The short and the long argument lists are the expected lists of arguments. The Console_Getopt::getopt() function returns an error object if the user enters an invalid argument that is not listed in the short or long expected argument list passed to it. If the user enters valid arguments and argument options, the getopt() method returns the list of options supplied by the user in an array. The getCommandLineOptions() function goes through the valid list of user-entered arguments, removes - characters from each argument, and makes an associative array called $cmd, using the argument name as the key and the argument value as the value. For example, if the user runs this script as follows: ./cmd_options.php -h -s 100 the $cmd array looks like the following: Array ( [h] => 1 [s] => 100 ) Similarly, if the user runs it as ./cmd_options.php -h –size 100 –king=burger the $cmd array looks like the following: Array ( [h] => 1 [size] => 100 [king] => burger )
Posted in JSP | No Comments »
March 17th, 2008
566 Part IV: Using PHP for Sysadmin Tasks Listing 16-4 (Continued) function getCommandLineOptions($options) { $type = gettype($options); if (gettype($options) != array ) { // Error in command line echo $options->message n ; return null; } $cmd = array(); foreach ($options[0] as $argArray) { $argName = preg_replace( /[^w]/ , , $argArray[0]); $argValue = $argArray[1]; $cmd[$argName] = ($argValue != ) ? $argValue : TRUE; } return (count($cmd) > 0) ? $cmd : null; } ?> Here, getCommandLineOptions() is passed the output of the Console_Getopt::getopt() function. The Console_Getopt::getopt() function takes $GLOBALS[ argv ], $CMD_SHORT_OPTIONS, and $CMD_LONG_OPTIONS as arguments. The $GLOBALS[ argv ] argument is same as $argv, which holds the user- supplied command-line arguments. The second argument, $CMD_SHORT_OPTIONS, is a list of short argument options such as hs: . These are the options that a user can enter as h and -s size. The -s option takes a value and therefore : is added in the $CMD_SHORT_OPTIONS string to indicate that. The $CMD_LONG_OPTIONS is set to an array such as array( help , size= ). These arguments can be entered by the user as help and –size=size.
Posted in JSP | No Comments »
March 16th, 2008
Chapter 16: Command-Line PHP Utilities 565 Console_Getopt::getopt ( $GLOBALS[ argv ], $CMD_SHORT_OPTIONS, $CMD_LONG_OPTIONS ) ); if ($cmd == null) { syntax(); } else if (isset($cmd[ h ]) || isset($cmd[ help ])) { echo You selected help option.n ; } if (isset($cmd[ s ]) || isset($cmd[ size ])) { echo You selected size option. Chosen size is . $cmd[ s ] . . $cmd[ size ] . n ; } exit; function syntax() { $script = basename($GLOBALS[ argv ][0]); echo<<
Posted in JSP | No Comments »
March 16th, 2008
564 Part IV: Using PHP for Sysadmin Tasks Listing 16-3: arg.php #!/usr/bin/php -q When this script is run as follows: ./args.php -h -k -x 100 it prints the following: Array ( [0] => ./arg.php [1] => -h [2] => -k [3] => -x [4] => 100 ) The $argv array is created by PHP, which stores all the command-line arguments as shown in the preceding output. However, it is not the most efficient way to deal with command arguments. Listing 16-4 shows a script called cmd_options.php, which uses the Console/Getopt.php class from the PEAR package. Listing 16-4: cmd_options.php #!/usr/bin/php -q
Posted in JSP | No Comments »
March 15th, 2008
Chapter 16: Command-Line PHP Utilities 563 $keyboardBuffer = null; if ($STDIN) { while(($ch = fgetc($STDIN)) != n ) { $keyboardBuffer .= $ch; } fclose($STDIN); } return $keyboardBuffer; } ?> The script calls a function called prompt(), which takes a string message and displays it on the shell screen. The prompt() function calls another function called getSTDIN(), which opens a file handle called $STDIN to /dev/stdin (i.e., php://stdin) and reads characters from it until a newline (n) character is entered by the user. This effectively gives us the command line entered by the user. The user- entered data is stored in a string buffer called $keyboardBuffer, which is returned to the caller of getSTDIN(). The PHP 4.3.x version of the command-line PHP binary with CLI enabled (–enable-cli) has STDIN, STDOUT, and STDERR constants predefined. These constants replace the following code: // STDIN constant replaces: $stdin = fopen( php://stdin , r ); // STDOUT constant replaces: $stdout = fopen( php://stdout , w ); // STDERR constant replaceS: $stderr = fopen( php://stderr , w ); Getting into arguments You will often need to get command-line arguments from the user. Listing 16-3 shows a simple script called arg.php, which prints out an array called $argv.
Posted in JSP | No Comments »
March 15th, 2008
562 Part IV: Using PHP for Sysadmin Tasks It s good practice to get in the habit of using the q option when running PHP from the command line to suppress the HTML headers. That way you are sure to suppress the headers. In the 4.3.x version of PHP (compiled with the –enable-cli option), you can also run the following: php q -r echo Your PHP Code ; Here, the echo statement will be executed as if it were in a script. This type of execution is not suitable for most real problem-solving work. It is most useful when you want to write a quick and dirty script for one-time use. Reading standard input Reading input from the shell is a common task performed by a command-line script. Listing 16-2 shows a simple script called ask.php, which reads user input from a command-line prompt. Listing 16-2: ask.php #!/usr/bin/php -q
Posted in JSP | No Comments »
March 15th, 2008
Chapter 16: Command-Line PHP Utilities 561 These options are not necessary for running command-line scripts because most command-line scripts under a Linux/UNIX system are run by adding the interpreter path as the first line. For example, Listing 16-1 shows a simple PHP script called helloworld.php. Listing 16-1: helloworld.php #!/usr/bin/php -q In PHP Version 4.3.x, the -q option is not needed if the PHP binary is compiled with the –enable-cli option, which enables Command Line Interface (CLI) support and automatically suppresses HTTP headers. Earlier versions of PHP supported multiple options, but only one option would actually work. In the preceding code, the first line starts with #! and is followed by the fully qualified path name of the PHP command-line interpreter. The next line is the starting tag for the PHP script. After making the file executable by running the chmod 755 helloworld.php command, you can run it from the script s current directory as follows: ./helloworld.php Following is sample output: Hello World When the helloworld.php script is run from the shell, the shell loads this file and locates the first line (#!, called the bang line) and runs the script using the named interpreter. All the scripts discussed in this chapter run this way. However, you can also run PHP scripts as follows: php q filename.php where filename.php is your script.
Posted in JSP | No Comments »