Book HomePHP CookbookSearch this book

Chapter 20. Client-Side PHP

20.1. Introduction

PHP was created for web programming and is still used mostly for that purpose. However, newer versions of PHP are increasingly more capable as a general-purpose scripting language. Using PHP for scripts you run from the command line is especially helpful when they share code with your web applications. If you have a discussion board on your web site, you might want to run a program every few minutes or hours to scan new postings and alert you to any messages that contain certain keywords. Writing this scanning program in PHP lets you share relevant discussion-board code with the main discussion-board application. Not only does this save you time, but also helps avoid maintenance overhead down the road.

With the PHP-GTK extension, your command-line PHP programs can be full-featured GUI applications. These can also share code with PHP web applications and text-based command-line programs. Like PHP, PHP-GTK is cross-platform, so the same code runs on Unix and Windows.

The same PHP binary built to be executed as a CGI program can be run from the command line. To run a script, pass the script filename as an argument:

% php scan-discussions.php

On Unix, you can also use the "hash-bang" syntax at the top of your scripts to run the PHP interpreter automatically. If the PHP binary is in /usr/local/bin, make the first line of your script:

#!/usr/local/bin/php

You can then run the script just by typing its name on the command line, as long as the file has execute permission.

Command-line PHP scripts almost always use the -q flag, which prevents PHP from printing HTTP response headers at the beginning of its output:

% php -q scan-discussions.php

You can also use this:

#!/usr/local/bin/php -q

Another helpful option on the command line is the -c flag, which lets you specify an alternate php.ini file to load settings from. If your default php.ini file is /usr/local/lib/php.ini, it can be helpful to have a separate configuration file at /usr/local/lib/php-commandline.ini with settings such as max_execution_time = 0; this ensures that your scripts don't quit after 30 seconds. Here's how to use this alternate file:

% php -q -c /usr/local/lib/php-commandline.ini scan-discussions.php

You can also use this :

#!/usr/local/bin/php -q -c /usr/local/lib/php-commandline.ini

If it's likely that you'll use some of your classes and functions both for the web and for the command line, abstract the code that needs to react differently in those different circumstances, such as HTML versus plain-text output or access to environment variables that a web server sets up. A useful tactic is to make your code aware of a global variable called $COMMAND_LINE. Set this to true at the top of your command-line scripts. You can then branch your scripts' behavior as follows:

if ($GLOBALS['COMMAND_LINE']) {
  print "Database error: ".mysql_error()."\n";
} else {
  print "Database error.<br>";
  error_log(mysql_error());
}

This code not only adjusts the output formatting based on the context it's executing in (\n versus <br>), but also where the information goes. On the command line, it's helpful to the person running the program to see the error message from MySQL, but on the Web, you don't want your users to see potentially sensitive data. Instead, the code outputs a generic error message and stores the details in the server's error log for private review.

Beginning with Version 4.3, PHP builds include a command-line interface (CLI) binary.[17] The CLI binary is similar to the CGI binary but has some important differences that make it more shell-friendly. Some configuration directives have hardcoded values with CLI; for example, the html_errors directive is set to false, and implicit_flush is set to true. The max_execution_time directive is set to 0, allowing unlimited program runtime. Finally, register_argc_argv is set to true. This means you can look for argument information in $argv and $argc instead of in $_SERVER['argv'] and $_SERVER['argc']. Argument processing is discussed in Recipe 20.2 and Recipe 20.3.

[17]The CLI binary can be built under 4.2.x versions by explicitly configuring PHP with --enable-cli.

The CLI binary accepts a slightly different set of arguments than the CGI binary. It doesn't accept the -q or -C flags because it does what these flags indicate by default. While -q tells the CGI binary not to print headers, the CLI binary never prints headers. Even the header( ) function produces no output under CLI. Similarly, the -C flag tells the CGI binary not to change to the directory of the script being run. The CLI binary never changes to the script directory.

The CLI binary also takes one new argument: -r. When followed by some PHP code without <?php and ?> script tags, the CLI binary runs the code. For example, here's how to print the current time:

% php -r 'print strftime("%c");'

Finally, the CLI binary defines handles to the standard I/O streams as the constants STDIN, STDOUT, and STDERR. You can use these instead of creating your own file handles with fopen( ):

// read from standard in
$input = fgets(STDIN,1024);

// write to standard out
fwrite(STDOUT,$jokebook);

// write to standard error
fwrite(STDERR,$error_code);

If you're using the CLI binary, you can use php_sapi_name( ) instead of $GLOBALS['COMMAND_LINE'] to test whether a script is running in a web or command-line context:

if ('cli' == php_sapi_name()) {
  print "Database error: ".mysql_error()."\n";
} else {
  print "Database error.<br>";
  error_log(mysql_error());
}

You can use the CLI binary or the CGI binary to run programs that use the PHP-GTK extension. This extension is an interface to the GTK+ toolkit, which is a library of widgets, screen drawing code, and other necessary functions for building a GUI application.

Widgets are GUI interface elements such as buttons, scrollbars, windows, menus, and select boxes. To build a PHP-GTK application, your code must create widgets and arrange them on the screen. Recipe 20.6 shows how to create and display a widget, Recipe 20.7 shows how to arrange multiple widgets for display together, and Recipe 20.9 explains how to display a menu bar.

Widgets communicate with each other and with the rest of your program using signals. When something happens to a widget, it emits a signal; for example, when a button is clicked, it emits a clicked signal. Recipe 20.8 discusses how to capture these signals and take action when one is emitted. The sample application in Recipe 20.11 combines PHP-GTK with some SOAP function calls to display weather conditions around the world.

To install PHP-GTK on Unix, download the latest version of PHP-GTK from http://gtk.php.net/download.php and the GTK+ libraries from http://www.gtk.org/download. You also need libtool 1.4.2, automake 1.4, and autoconf 2.13 (available at http://www.gnu.org/directory/ if they're not already installed on your system).

Once you've downloaded all the necessary files and installed the support libraries and tools, unpack the PHP-GTK source distribution. In the PHP-GTK directory, run ./buildconf to create configuration files, ./configure to create makefiles, then make to build the PHP-GTK extension. Last, run make install to install the PHP-GTK extension in your PHP extensions directory. You can find detailed Unix installation instructions, including common build problems, at http://gtk.php.net/manual/en/install.unix.php.

To install PHP-GTK on Windows, no compiling is necessary. From http://gtk.php.net/download.php, you can download a compiled PHP-GTK extension and supporting libraries. Once you've downloaded and unzipped the Windows distribution, copy the files in the php4 subdirectory to your PHP binary directory (or create one if it doesn't already exist). Copy the files in the winnt\system32 subdirectory to your system32 directory (C:\WINNT\SYSTEM32 for Windows NT and Windows 2000; C:\WINDOWS\SYSTEM32 for Windows 95 and Windows 98). If you don't already have a php.ini file in place, copy the winnt\php.ini file to your Windows directory (C:\WINNT or C:\WINDOWS). If you already have a php.ini file in place, add these lines to the end of it:

[PHP-GTK]
php-gtk.extensions = php_gtk_libglade.dll, php_gtk_sqpane.dll

Detailed Windows installation instructions are at http://gtk.php.net/manual/en/install.win32.php.

On either platform, once you've installed the PHP-GTK extension, you need to use the dl( ) function to load it in any script in which you want to use GTK functionality. On Windows:

if (! class_exists('gtk')) {
    dl('php_gtk.dll');
}

On Unix:

if (! class_exists('gtk')) {
    dl('php_gtk.so');
}

If you want the same script to run unaltered on Unix or Windows, you can load the PHP-GTK extension like this:

if (! class_exists('gtk')) {
    dl('php_gtk.'. (((strtoupper(substr(PHP_OS,0,3))) == 'WIN')?'dll':'so'));
}

The GTK+ toolkit is large and powerful. PHP-GTK makes it easy to create and manipulate GTK+ objects, but designing and planning a GUI application is still a significant task. In addition to the comprehensive PHP-GTK documentation at http://gtk.php.net/manual/, also take advantage of the GTK+ documentation itself at http://developer.gnome.org/doc/API/gtk/index.html. The C class and function names in the GTK+ documentation map almost directly to their PHP equivalents. Also, the tutorial at http://www.gtk.org/tutorial/ is for GTK+ 2.0 (not 1.2), but it is still a good introduction to the concepts and practices of GTK+ application building.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.